BrowserActivity.java revision aac7aa6fcfcb519755987ec126be066323f589c8
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 com.google.android.googleapps.IGoogleLoginService;
200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport com.google.android.googlelogin.GoogleLoginServiceConstants;
210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.Activity;
230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.AlertDialog;
240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.ProgressDialog;
250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.SearchManager;
260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ActivityNotFoundException;
270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.BroadcastReceiver;
280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ComponentName;
290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentResolver;
30b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport android.content.ContentUris;
310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentValues;
320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Context;
330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface;
340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Intent;
350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.IntentFilter;
360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ServiceConnection;
370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface.OnCancelListener;
38b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.content.pm.PackageInfo;
390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.PackageManager;
400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.ResolveInfo;
410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.AssetManager;
420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Configuration;
430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Resources;
440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.Cursor;
450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.sqlite.SQLiteDatabase;
460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.sqlite.SQLiteException;
470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
48540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescuimport android.graphics.BitmapFactory;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.DrawFilter;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Paint;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.PaintFlagsDrawFilter;
530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
543bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.PixelFormat;
553bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scrogginsimport android.graphics.Rect;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.hardware.SensorListener;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.hardware.SensorManager;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
60eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scottimport android.net.NetworkInfo;
610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.EventHandler;
640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.IBinder;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.RemoteException;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.ServiceManager;
770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
795e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract;
805e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clarkimport android.provider.ContactsContract.Intents.Insert;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.IClipboard;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.util.Regex;
870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.AlphaAnimation;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.Animation;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.AnimationSet;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.DecelerateInterpolator;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.ScaleAnimation;
1060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.TranslateAnimation;
1070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
1080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
1090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
1102bc69918d97a767a02132090e58718077381ba1aSteve Blockimport android.webkit.GeolocationPermissions;
1110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
112b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
1130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
1140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
1150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
116c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescuimport android.webkit.WebChromeClient.CustomViewCallback;
1170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
119092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdochimport android.webkit.WebStorage;
1200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebViewClient;
1220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.BufferedOutputStream;
129b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.FileInputStream;
1320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.FileOutputStream;
1330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.IOException;
1340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.InputStream;
1350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URI;
1379918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.text.ParseException;
1410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Enumeration;
1430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
14437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scottimport java.util.LinkedList;
1450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Vector;
1460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.zip.ZipEntry;
1490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.zip.ZipFile;
1500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
1525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    implements View.OnCreateContextMenuListener,
1530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        DownloadListener {
1540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
15631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
15731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
15831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
15931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
16031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
16131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
1620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IGoogleLoginService mGls = null;
1630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ServiceConnection mGlsConnection = null;
1640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SensorManager mSensorManager = null;
1660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
167565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
168565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
169565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
170565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
171565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
172565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
173565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* Whitelisted webpages
1750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static HashSet<String> sWhiteList;
1760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    static {
1780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList = new HashSet<String>();
1790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("cnn.com/");
1800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("espn.go.com/");
1810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("nytimes.com/");
1820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("engadget.com/");
1830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("yahoo.com/");
1840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("msn.com/");
1850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("amazon.com/");
1860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("consumerist.com/");
1870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("google.com/m/news");
1880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
1890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    */
1900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setupHomePage() {
1920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Runnable getAccount = new Runnable() {
1930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void run() {
1940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Lower priority
1950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // get the default home page
1970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String homepage = mSettings.getHomePage();
1980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
2000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mGls == null) return;
2010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
202f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                    if (!homepage.startsWith("http://www.google.")) return;
203f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                    if (homepage.indexOf('?') == -1) return;
204f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba
2050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String hostedUser = mGls.getAccount(GoogleLoginServiceConstants.PREFER_HOSTED);
2060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String googleUser = mGls.getAccount(GoogleLoginServiceConstants.REQUIRE_GOOGLE);
2070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // three cases:
2090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser == googleUser
2110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has only a google account
2120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser != googleUser
2140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has a hosted account and a google account
2150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser != null, googleUser == null
2170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has only a hosted account (so far)
2180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // developers might have no accounts at all
2200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (hostedUser == null) return;
2210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (googleUser == null || !hostedUser.equals(googleUser)) {
2230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
224f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                        homepage = homepage.replace("?", "/a/" + domain + "?");
2250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
2260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (RemoteException ignore) {
2270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Login service died; carry on
2280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (RuntimeException ignore) {
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Login service died; carry on
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } finally {
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    finish(homepage);
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            private void finish(final String homepage) {
2360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.post(new Runnable() {
2370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void run() {
2380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mSettings.setHomePage(BrowserActivity.this, homepage);
2390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        resumeAfterCredentials();
2400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // as this is running in a separate thread,
2420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // BrowserActivity's onDestroy() may have been called,
2430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // which also calls unbindService().
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (mGlsConnection != null) {
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // we no longer need to keep GLS open
2460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            unbindService(mGlsConnection);
2470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mGlsConnection = null;
2480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
2490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } });
2500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } };
2510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final boolean[] done = { false };
2530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open a connection to the Google Login Service.  The first
2550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // time the connection is established, set up the homepage depending on
2560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the account in a background thread.
2570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mGlsConnection = new ServiceConnection() {
2580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void onServiceConnected(ComponentName className, IBinder service) {
2590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mGls = IGoogleLoginService.Stub.asInterface(service);
2600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (done[0] == false) {
2610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    done[0] = true;
2620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Thread account = new Thread(getAccount);
2630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    account.setName("GLSAccount");
2640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    account.start();
2650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void onServiceDisconnected(ComponentName className) {
2680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mGls = null;
2690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        };
2710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bindService(GoogleLoginServiceConstants.SERVICE_INTENT,
2730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mGlsConnection, Context.BIND_AUTO_CREATE);
2740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
276a977124eb29b195127fd161120ebbc58b255fb48Cary Clark    private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
2770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
2780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
2790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
2800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
281d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    if (!f.delete()) {
282d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                      Log.e(LOGTAG, f.getPath() + " was not deleted");
283d6be1758b38d5b066ff10b6af906aa66c63670cdCary Clark                    }
2840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
2870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
2913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * This layout holds everything you see below the status bar, including the
2923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * error console, the custom view container, and the webviews.
2933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
2943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private FrameLayout mBrowserFrameLayout;
29581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
2960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public void onCreate(Bundle icicle) {
29731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
2980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
2990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
3010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
3020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
3030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
3050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
3070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3080923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // If this was a web search request, pass it on to the default web
3090923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        // search provider and finish this activity.
3100923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (handleWebSearchIntent(getIntent())) {
3110923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            finish();
3120923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba            return;
3130923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        }
3140923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
3150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
3160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // start MASF proxy service
3170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
3180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
3190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
3200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //    (new ComponentName(
3210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
3220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
3230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //startService(proxyServiceIntent, null);
3240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
3260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
3280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
3290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
33181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
3323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
3333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
3343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
3353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
3363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
3373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
3383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
3393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
3403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
34168579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar = new TitleBar(this);
3420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
3440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
3450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
3470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
3480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
3500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
3510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
3520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.loadFromDb(this);
3530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
3550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
3560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
357a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
358a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
359a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
360a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
361a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
362a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
363a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
364a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
365a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
366a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
367eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                        NetworkInfo info =
368eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                                (NetworkInfo) intent.getParcelableExtra(
369eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                                        ConnectivityManager.EXTRA_NETWORK_INFO);
370eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                        onNetworkToggle(
371eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                                (info != null) ? info.isConnected() : false);
372a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
373a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
374a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
375a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
376615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
377615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
378615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
379615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
380615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
381615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
382615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
383615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
384615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
385615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
386615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
387615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
388615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
389615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
390615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
391615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
392615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
393615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
394615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
395615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
396615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
397615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
398615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
399615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
400615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
401615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
402615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
403615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
404615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
405615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
406615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
407615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
408615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
409615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
410615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
411615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
412615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
413615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                .refreshPlugins(
414615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
415615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                                .equals(action));
416615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
417615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
418615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
419615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
420615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
421615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
4230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
4260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
427aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
428aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
429aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
4300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
4310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
4350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
43625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
43725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
4380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab t = mTabControl.createNewTab(
4390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent.ACTION_VIEW.equals(intent.getAction()) &&
440f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    intent.getData() != null,
44125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
4420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
4430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
4440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
4450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
4460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
4470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
4480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
4490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
4500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we are not restoring from an icicle, then there is a high
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // likely hood this is the first run. So, check to see if the
4530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // homepage needs to be configured and copy any plugins from our
4540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // asset directory to the data partition.
4550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((extra == null || !extra.getBoolean("testing"))
4560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    && !mSettings.isLoginInitialized()) {
4570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                setupHomePage();
4580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
461304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                if (mSettings.isLoginInitialized()) {
462304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    webView.loadUrl(mSettings.getHomePage());
463304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                } else {
464304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    waitForCredentials();
465304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                }
4660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
46781678d9216458266ea70cd62d52f28f744873556Grace Kloba                if (extra != null) {
46881678d9216458266ea70cd62d52f28f744873556Grace Kloba                    urlData.setPostData(extra
46981678d9216458266ea70cd62d52f28f744873556Grace Kloba                            .getByteArray(Browser.EXTRA_POST_DATA));
47081678d9216458266ea70cd62d52f28f744873556Grace Kloba                }
47125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData.loadIn(webView);
4720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
4740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
4751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
4760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
4770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
478615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
479b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
480b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
481b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
482b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
483b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
4840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
4850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
4880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
4890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
5000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
5010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
5030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
5040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
5050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
5060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
5070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
5080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
5100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
5110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
5120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_WEB_SEARCH.equals(action)) {
513565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
514565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
515565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
516565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
517565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
518565505b1a2c1d3099496af5910760087602e994aSatish Sampath
51925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
52025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
52125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
5220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
52381678d9216458266ea70cd62d52f28f744873556Grace Kloba            urlData.setPostData(intent
52481678d9216458266ea70cd62d52f28f744873556Grace Kloba                    .getByteArrayExtra(Browser.EXTRA_POST_DATA));
52525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
526cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
527cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
528cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            if (Intent.ACTION_VIEW.equals(action)
529cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
530cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
531cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                TabControl.Tab appTab = mTabControl.getTabFromId(appId);
532f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
533f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
534f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
535f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
536f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
537f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
538f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
539f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
540f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
541f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
542f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
54325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            mTabControl.recreateWebView(appTab, urlData.mUrl);
544bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
545f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
5461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
5471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            urlData.loadIn(appTab.getWebView());
5491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
550f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
5511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
5521f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
5531f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
5541f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            urlData.loadIn(appTab.getWebView());
556f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
557f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
558f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
559cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
560cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
561cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
562cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
56325515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
56425515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
56525515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
56625515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
56725515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
568cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
569cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
570cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
571cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
572cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
573cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
575cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
576f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
57825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("about:debug".equals(urlData.mUrl)) {
5790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSettings.toggleDebugSettings();
5800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5821f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5831f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
5841f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                urlData.loadIn(current.getWebView());
5850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
589565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
590565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
591565505b1a2c1d3099496af5910760087602e994aSatish Sampath
592565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
597565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
598565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
599565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
600565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
601565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
602565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
603565505b1a2c1d3099496af5910760087602e994aSatish Sampath
604565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
605565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
606565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
607565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
608565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
609565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
610565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
611565505b1a2c1d3099496af5910760087602e994aSatish Sampath
612565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
613565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
614565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
615565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getData().toString();
616565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
617565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
618565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
620565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
6210485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
6220485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
623565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
624565505b1a2c1d3099496af5910760087602e994aSatish Sampath
625565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
626565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
627565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
628565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
629565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
6300485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
631565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
632565505b1a2c1d3099496af5910760087602e994aSatish Sampath
633565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
634565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
635565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
636565505b1a2c1d3099496af5910760087602e994aSatish Sampath
637565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
638565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
639565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Regex.WEB_URL_PATTERN.matcher(url).matches()
640bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
641565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
642565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
643565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
644565505b1a2c1d3099496af5910760087602e994aSatish Sampath
645565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.updateVisitedHistory(mResolver, url, false);
646565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.addSearchUrl(mResolver, url);
647565505b1a2c1d3099496af5910760087602e994aSatish Sampath
648565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
649565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
650565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
65115e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
65215e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
65315e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6540485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6550485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6560485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
657cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
658565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
659565505b1a2c1d3099496af5910760087602e994aSatish Sampath
660565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
661565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
662565505b1a2c1d3099496af5910760087602e994aSatish Sampath
66325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
67625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("inline:".equals(url)) {
67725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    return new InlinedUrlData(
67825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_CONTENT),
67925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getType(),
68025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_ENCODING),
68125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_FAILURL));
68225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
6890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Don't add Urls, just search terms.
6900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Urls will get added when the page is loaded.
6910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!Regex.WEB_URL_PATTERN.matcher(url).matches()) {
6920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Browser.updateVisitedHistory(mResolver, url, false);
6930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = appData.getString(SearchManager.SOURCE);
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
7060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
7070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
7090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
71325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        return new UrlData(url);
7140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
717652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
718652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
719652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
720652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
721652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
722652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
723652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
724652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
725652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
726652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
727652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
728652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
729652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
730652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
731652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
732652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
733652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
734652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
7470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Looking for the pattern like this
7480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
7490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *          *
7500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *         * *
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *      ***   *     *******
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *             *   *
7530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *              * *
7540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *               *
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final SensorListener mSensorListener = new SensorListener() {
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private long mLastGestureTime;
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrev = new float[3];
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrevDiff = new float[3];
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mDiff = new float[3];
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mRevertDiff = new float[3];
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onSensorChanged(int sensor, float[] values) {
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean show = false;
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            float[] diff = new float[3];
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            for (int i = 0; i < 3; i++) {
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                diff[i] = values[i] - mPrev[i];
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Math.abs(diff[i]) > 1) {
7700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    show = true;
7710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((diff[i] > 1.0 && mDiff[i] < 0.2)
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        || (diff[i] < -1.0 && mDiff[i] > -0.2)) {
7740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // start track when there is a big move, or revert
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mRevertDiff[i] = mDiff[i];
7760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = 0;
7770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else if (diff[i] > -0.2 && diff[i] < 0.2) {
7780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // reset when it is flat
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = mRevertDiff[i]  = 0;
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mDiff[i] += diff[i];
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrevDiff[i] = diff[i];
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrev[i] = values[i];
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
7870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only shows if we think the delta is big enough, in an attempt
7880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // to detect "serious" moves left/right or up/down
7890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "sensorChanged " + sensor + " ("
7900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + values[0] + ", " + values[1] + ", " + values[2] + ")"
7910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + " diff(" + diff[0] + " " + diff[1] + " " + diff[2]
7920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + ")");
7930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "      mDiff(" + mDiff[0] + " "
7940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mDiff[1] + " " + mDiff[2] + ")" + " mRevertDiff("
7950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[0] + " " + mRevertDiff[1] + " "
7960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[2] + ")");
7970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            long now = android.os.SystemClock.uptimeMillis();
8000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (now - mLastGestureTime > 1000) {
8010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mLastGestureTime = 0;
8020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float y = mDiff[1];
8040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float z = mDiff[2];
8050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ay = Math.abs(y);
8060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float az = Math.abs(z);
8070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ry = mRevertDiff[1];
8080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float rz = mRevertDiff[2];
8090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ary = Math.abs(ry);
8100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float arz = Math.abs(rz);
8110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestY = ay > 2.5f && ary > 1.0f && ay > ary;
8120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestZ = az > 3.5f && arz > 1.0f && az > arz;
8130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((gestY || gestZ) && !(gestY && gestZ)) {
8150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = mTabControl.getCurrentWebView();
8160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (view != null) {
8180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (gestZ) {
8190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (z < 0) {
8200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomOut();
8210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            } else {
8220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomIn();
8230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
8240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
8250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            view.flingScroll(0, Math.round(y * 100));
8260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
8270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
8280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastGestureTime = now;
8290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
8300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onAccuracyChanged(int sensor, int accuracy) {
8340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TODO Auto-generated method stub
8350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
8380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onResume() {
8400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
84131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
8420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
8430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
8460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
8470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
8480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8507bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
8510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
8527bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
8530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
8550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
8560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
8570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null) {
8600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
8610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // In case credential request never comes back
8620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
8630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
8670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
8680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
8690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.doFlick()) {
8710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSensorManager == null) {
8720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSensorManager = (SensorManager) getSystemService(
8730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Context.SENSOR_SERVICE);
8740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.registerListener(mSensorListener,
8760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_ACCELEROMETER,
8770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_DELAY_FASTEST);
8780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
8790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager = null;
8800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
8820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
8853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * would change its appearance, create a temporary title bar to go at
8863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * the top of the screen while the menu is open.
8873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
8893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
891d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Holder for the fake title bar.  It will have a foreground shadow, as well
892d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * as a white background, so the fake title bar looks like the real one.
893d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
894d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private ViewGroup mFakeTitleBarHolder;
895d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins
896d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
897d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Layout parameters for the fake title bar within mFakeTitleBarHolder
898d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
899d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private FrameLayout.LayoutParams mFakeTitleBarParams
900d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            = new FrameLayout.LayoutParams(
901c01e4a8342c9478f9ba0c53c2ebca25b4b5c3173Leon Scroggins            ViewGroup.LayoutParams.FILL_PARENT,
902d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            ViewGroup.LayoutParams.WRAP_CONTENT);
903d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
9043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
9053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
9063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
9073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
9083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
9103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
9113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
9123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
9133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
9143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
9153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
9163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
9183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
9193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
9203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
9213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
9223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
9233bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
924a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
925a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
9263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
9273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
9283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
9293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
9303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
9313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
9323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
9333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
9343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
9353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
9363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
9373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
9383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
9393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
9403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
9413bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
9423bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
9433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
9443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
9453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
9463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
9473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
9483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
9493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
9503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
9513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
9523bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
9533bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
954a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
955a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
956a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
9573bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
958f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott        final View decor = getWindow().peekDecorView();
9594d7e406998028f9ddb01df6d7463b87d6fa02601Leon Scroggins        if (mFakeTitleBar == null && mActiveTabsPage == null
960f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && !mActivityInPause && decor != null
961f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && decor.getWindowToken() != null) {
962f4bb18a41259ce62209c768484547d33583f9c77Leon Scroggins            final WebView webView = getTopWindow();
96368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            mFakeTitleBar = new TitleBar(this);
9643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setTitleAndUrl(null, webView.getUrl());
9653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setProgress(webView.getProgress());
9663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setFavicon(webView.getFavicon());
9673bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            updateLockIconToLatest();
9683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
9703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
9713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
9733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
9743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
9753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
9763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.FILL_PARENT,
9773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
9783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
9793bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
980685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
9813bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
982a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            WebView mainView = mTabControl.getCurrentWebView();
983685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            boolean atTop = mainView != null && mainView.getScrollY() == 0;
984685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            params.windowAnimations = atTop ? 0
985685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    : com.android.internal.R.style.Animation_DropDownDown;
9863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // XXX : Without providing an offset, the fake title bar will be
9873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // placed underneath the status bar.  Use the global visible rect
9883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // of mBrowserFrameLayout to determine the bottom of the status bar
9893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            Rect rectangle = new Rect();
9903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mBrowserFrameLayout.getGlobalVisibleRect(rectangle);
9913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.y = rectangle.top;
992685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // Add a holder for the title bar.  It also holds a shadow to show
993685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // below the title bar.
994d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            if (mFakeTitleBarHolder == null) {
995d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                mFakeTitleBarHolder = (ViewGroup) LayoutInflater.from(this)
996d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                    .inflate(R.layout.title_bar_bg, null);
997d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            }
998685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            mFakeTitleBarHolder.addView(mFakeTitleBar, 0, mFakeTitleBarParams);
999d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            manager.addView(mFakeTitleBarHolder, params);
10003bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
10013bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
10023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
10033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
10043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
10053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
1006a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
1007a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
1008a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
1009a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
1010a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
1011a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
1012a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
1013a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
10143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
10153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
10163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (mFakeTitleBar == null) return;
101720329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WindowManager.LayoutParams params = (WindowManager.LayoutParams)
101820329570ba9409637298da90b83f25801d7a3d55Leon Scroggins                mFakeTitleBarHolder.getLayoutParams();
101920329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        WebView mainView = mTabControl.getCurrentWebView();
102020329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // Although we decided whether or not to animate based on the current
102120329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // scroll position, the scroll position may have changed since the
102220329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // fake title bar was displayed.  Make sure it has the appropriate
102320329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        // animation/lack thereof before removing.
102420329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        params.windowAnimations = mainView != null && mainView.getScrollY() == 0
102520329570ba9409637298da90b83f25801d7a3d55Leon Scroggins                ? 0 : com.android.internal.R.style.Animation_DropDownDown;
10263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
10273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
102820329570ba9409637298da90b83f25801d7a3d55Leon Scroggins        manager.updateViewLayout(mFakeTitleBarHolder, params);
1029d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        mFakeTitleBarHolder.removeView(mFakeTitleBar);
1030d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        manager.removeView(mFakeTitleBarHolder);
10313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mFakeTitleBar = null;
10323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
10333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
1035c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * Special method for the fake title bar to call when displaying its context
1036c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * menu, since it is in its own Window, and its parent does not show a
1037c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     * context menu.
1038c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins     */
1039c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /* package */ void showTitleBarContextMenu() {
1040c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins        openContextMenu(mTitleBar);
1041c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    }
1042c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins
1043c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins    /**
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onSaveInstanceState(Bundle outState) {
104931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onPause() {
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
10640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
10670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
10680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10707bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
10710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
10727bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the credentials toast if it is up
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null && mCredsDlg.isShowing()) {
10800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
10830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1084a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
1085a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
1086a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
1087a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
1088a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
1089a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
1090a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
1091a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
10920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
10930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSensorManager != null) {
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.unregisterListener(mSensorListener);
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onDestroy() {
110431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
11080923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
11090923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba        if (mTabControl == null) return;
11100923d69a8ca45222cabd82a80eaa88da9f132e9aGrace Kloba
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab t = mTabControl.getCurrentTab();
1113fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1114fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1115fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1116fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mGlsConnection != null) {
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            unbindService(mGlsConnection);
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mGlsConnection = null;
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // stop MASF proxy service
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //   (new ComponentName(
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //stopService(proxyServiceIntent);
1134b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
1135b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
11403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoFromShowSSLCertificateOnError.booleanValue());
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
11620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
11670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mFindDialog != null && mFindDialog.isShowing()) {
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mFindDialog.onConfigurationChanged(newConfig);
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public void onLowMemory() {
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11857bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean resumeWebViewTimers() {
11860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if ((!mActivityInPause && !mPageStarted) ||
11870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (mActivityInPause && mPageStarted)) {
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
11890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11997bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause && !mPageStarted) {
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
12080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // FIXME: Do we want to call this when loading google for the first time?
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called when we are launching for the first time. We
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * are waiting for the login credentials before loading Google home
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * pages. This way the user will be logged in straight away.
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void waitForCredentials() {
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show a toast
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = new ProgressDialog(this);
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setIndeterminate(true);
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the user cancels the operation, then cancel the Google
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Credentials request.
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.show();
12270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // We set a timeout for the retrieval of credentials in onResume()
12290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // as that is when we have freed up some CPU time to get
12300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the login credentials.
12310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
12340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If we have received the credentials or we have timed out and we are
12350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * showing the credentials dialog, then it is time to move on.
12360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resumeAfterCredentials() {
12380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg == null) {
12390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the toast
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg.isShowing()) {
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
12450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
12470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear any pending timeout
12490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
12500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the page
12520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
12530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
12540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.loadUrl(mSettings.getHomePage());
12550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Update the settings, need to do this last as it can take a moment
12580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to persist the settings. In the mean time we could be loading
12590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // content.
12600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setLoginInitialized(this);
12610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
12640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
12650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
12660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
12670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
12680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Cursor c = Browser.getAllBookmarks(mResolver);
12690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!c.moveToFirst()) {
12700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.deactivate();
12710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
12720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
12740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            do {
12750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = c.getString(urlIndex);
12760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                db.retainIconForPageUrl(url);
12770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } while (c.moveToNext());
12780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            c.deactivate();
12790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
12800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
12810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
12850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
12860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
12870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
12910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
12920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
12940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
12950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
12960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
12970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
12980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
13010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
13020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
13030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
13040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
13050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
13060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
13070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
13080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
13120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
13130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
13140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
13150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
13190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
13200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
13210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
13220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
13230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
1324c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            // For the context menu from the title bar
1325c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_share_page_url:
1326c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins            case R.id.title_bar_copy_page_url:
1327c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                WebView mainView = mTabControl.getCurrentWebView();
1328c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == mainView) {
1329c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                    return false;
1330c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1331c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (id == R.id.title_bar_share_page_url) {
1332c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                    Browser.sendString(this, mainView.getUrl());
1333c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                } else {
1334c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                    copy(mainView.getUrl());
1335c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1336c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                break;
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
13380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
13390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
13400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
13410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
13420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
13430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
1344c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final WebView webView = getTopWindow();
1345c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                if (null == webView) {
1346c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                    return false;
1347c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                }
1348c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final HashMap hrefMap = new HashMap();
1349c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                hrefMap.put("webview", webView);
1350c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                final Message msg = mHandler.obtainMessage(
1351c6fa1104e549b8f5b89195d22c41059e77672dfaLeon Scroggins                        FOCUS_NODE_HREF, id, 0, hrefMap);
13520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
13530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
13560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
13570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return onOptionsItemSelected(item);
13580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
13600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
13610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bundle.putString(SearchManager.SOURCE, source);
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
13704e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project     * Overriding this to insert a local information bundle
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onSearchRequested() {
137468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
13755bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
137683f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
13774e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
13780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
13790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
13830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
13840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
13850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
13860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
13880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13901f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
13911f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
13921f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1393160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1394160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1395160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1396160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1397160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
13981f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1399160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
14001f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        TabControl.Tab tab = mTabControl.getTab(index);
14011f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        TabControl.Tab currentTab = mTabControl.getCurrentTab();
14021f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1403160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
14041f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
14051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
14061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
14071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
14081f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
14091f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
14101f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
14111f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1412eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1413eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1414160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
14151f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
14161f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
14170a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ TabControl.Tab openTabToHomePage() {
14180a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
14190a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
14200a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14211f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
14221f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        final TabControl.Tab current = mTabControl.getCurrentTab();
1423160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1424304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1425304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
14260a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            TabControl.Tab newTab = openTabToHomePage();
1427160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1428160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1429160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
14301f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        final TabControl.Tab parent = current.getParentTab();
14311f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
14321f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
14331f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
14341f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1435160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1436160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1437160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1438160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1439160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1440160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
14411f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
14421f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1443160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1444160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1445160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1446160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
14471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
14481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
14490a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
14500a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14510a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
14520a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
14530a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
14540a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
14550a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
14560a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
14570a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
14580a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
14590a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
14600a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
14610a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
14620a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
14630a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
14640a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
14650a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
14680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14731f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
14740d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
14750d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
14766ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
14776ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
14786ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
14796ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
14806ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
14816ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
14826ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1485a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
14860a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1487a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1488a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
148964b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
1490304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14930a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
14940a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
14950a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
149643de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
14970a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
14980a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
14990a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
15000a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
15010a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
15021f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
15031f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                Intent i = new Intent(BrowserActivity.this,
15041f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        AddBookmarkPage.class);
15051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView w = getTopWindow();
15061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("url", w.getUrl());
15071f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("title", w.getTitle());
150883cdb2c40f2dbcbdf522a2af0ec8224c7195c6c1Grace Kloba                i.putExtra("touch_icon_url", w.getTouchIconUrl());
1509dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                i.putExtra("thumbnail", createScreenshot(w));
15101f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                startActivity(i);
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
15300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
15330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15351f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
15360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TabControl.Tab current = mTabControl.getCurrentTab();
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
15410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
15420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current.getWebView().loadUrl(mSettings.getHomePage());
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.setWebView(getTopWindow());
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.show();
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
15650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
15660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1569304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
157310fdba8a1a4598e7081c150f551c15dbe4a55634Andrei Popescu                Browser.sendString(this, getTopWindow().getUrl(),
157410fdba8a1a4598e7081c150f551c15dbe4a55634Andrei Popescu                        getText(R.string.choosertitle_sharevia).toString());
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
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) {
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            TabControl.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
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onPrepareOptionsMenu(Menu menu)
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    {
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(
1672a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                        mTabControl.getTabCount() < TabControl.MAX_TABS);
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);
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
17240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
17280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
17290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
17300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
17310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
17360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
17370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
17415e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
17510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
17710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
17720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
17730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
17740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
17750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
17760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getTabCount() < TabControl.MAX_TABS);
17770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
17790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
17820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
17830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
17840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
17860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
17870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
17880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
17890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
17910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
17920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
17930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
17940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
17980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1803c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
18040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachTabToContentView(TabControl.Tab t) {
18052bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
18062bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1807d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1808bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1809bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
1810bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(true);
1811bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1812bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1813bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1814bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1815bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1816bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1817bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
1818bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
1819bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1820bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1821bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1822c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        setLockIconType(t.getLockIconType());
1823c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        setPrevLockType(t.getPrevLockIconType());
1824c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba
1825c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        // this is to match the code in removeTabFromContentView()
1826c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        if (!mPageStarted && t.getTopWindow().getProgress() < 100) {
1827c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            mPageStarted = true;
1828eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        }
1829eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba
183039ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
183155a5bc2a8f3c9a0721eeaa5a45241e00d5da95efLeon Scroggins        view.setEmbeddedTitleBar(mTitleBar);
18320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
18330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
18340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachSubWindow(TabControl.Tab t) {
1838d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1839d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
18430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void removeTabFromContentView(TabControl.Tab t) {
18442bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1845d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1846bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1847bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mTabControl.getCurrentErrorConsole(false) != null) {
1848bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(mTabControl.getCurrentErrorConsole(false));
1849bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1850bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
185139ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
1852bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        if (view != null) {
1853bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins            view.setEmbeddedTitleBar(null);
1854bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
185539ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins
1856c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        // unlike attachTabToContentView(), removeTabFromContentView() can be
1857c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        // called for the non-current tab. Need to add the check.
1858eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        if (t == mTabControl.getCurrentTab()) {
1859eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            t.setLockIconType(getLockIconType());
1860eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            t.setPrevLockIconType(getPrevLockType());
1861c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba
1862c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // this is not a perfect solution. But currently there is one
1863c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // WebViewClient for all the WebView. if user switches from an
1864c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // in-load window to an already loaded window, mPageStarted will not
1865c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // be set to false. If user leaves the Browser, pauseWebViewTimers()
1866c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // won't do anything and leaves the timer running even Browser is in
1867c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // the background.
1868c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            if (mPageStarted) {
1869c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba                mPageStarted = false;
1870c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            }
1871eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        }
18720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
18750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
18760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void dismissSubWindow(TabControl.Tab t) {
1877d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
1878d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        // Tell the TabControl to dismiss the subwindow. This will destroy
1879d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        // the WebView.
1880d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        mTabControl.dismissSubWindow(t);
1881d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18841f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
188525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
18861f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    private TabControl.Tab openTabAndShow(String url, boolean closeOnExit,
18871f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            String appId) {
18881f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
18890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
18920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
18931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
18941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ TabControl.Tab openTabAndShow(UrlData urlData,
1895f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            boolean closeOnExit, String appId) {
18960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final boolean newTab = mTabControl.getTabCount() != TabControl.MAX_TABS;
18970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab currentTab = mTabControl.getCurrentTab();
18980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (newTab) {
18991f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            final TabControl.Tab tab = mTabControl.createNewTab(
19001f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                    closeOnExit, appId, urlData.mUrl);
19011f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
19020a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
19030a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
19040a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
19050a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
19060a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
19078bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
19088bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
19098bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1910eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1911160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
19121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                urlData.loadIn(webview);
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
191564b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
19161f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
19171f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
19181f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
19191f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
19201f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                urlData.loadIn(currentTab.getWebView());
19210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1923c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba        return currentTab;
19240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1926c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba    private TabControl.Tab openTab(String url) {
19270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
1928f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            TabControl.Tab t = mTabControl.createNewTab();
19290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
19301f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
19311f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                view.loadUrl(url);
19320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1933c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
19340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
19351f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
19400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
19410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
19530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
19540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
19570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
19610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
19620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
19660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
19690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
19700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
19720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
19730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
19790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
19800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
19820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
19850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        revertLockIcon();
19860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
19870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
19910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
19930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
19940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
19950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebChromeClient.onProgressChanged(current, progress);
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
20030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
200668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
200968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
201968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private void setUrlTitle(String url, String title) {
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
202368579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setTitleAndUrl(title, url);
20243bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (mFakeTitleBar != null) {
20253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setTitleAndUrl(title, url);
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
203732e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
20480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
20490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
20530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
20540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
20550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
20580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
20640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setFavicon(Bitmap icon) {
206868579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
20693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (mFakeTitleBar != null) {
20703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setFavicon(icon);
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Saves the current lock-icon state before resetting
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the lock icon. If we have an error, we may need to
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * roll back to the previous state.
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void saveLockIcon() {
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPrevLockType = mLockIconType;
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reverts the lock-icon state to the last saved state,
20850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * for example, if we had an error, and need to cancel
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the load.
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void revertLockIcon() {
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = mPrevLockType;
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
209131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.revertLockIcon:" +
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  " revert lock icon to " + mLockIconType);
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        updateLockIconToLatest();
20970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20991f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
21000a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
21010a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
21021f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
21030a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void closeTab(TabControl.Tab t) {
21040a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
21050a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
21061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
21070a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
21080a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
21090a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
21100a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2111a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
21120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void goBackOnePageOrQuit() {
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
21160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
21180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
21190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
21200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
21210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
21220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
212500d85e74921459b34e70eb93368245b4c0a9bf5fGrace Kloba            return;
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
21300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
21330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            TabControl.Tab parent = current.getParentTab();
21340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
21351f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
21361f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
21371f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
21380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
2140bb0af5ced906e5100d54f0c08e073e669edf2290Grace Kloba                    // force mPageStarted to be false as we are going to either
2141bb0af5ced906e5100d54f0c08e073e669edf2290Grace Kloba                    // finish the activity or remove the tab. This will ensure
2142bb0af5ced906e5100d54f0c08e073e669edf2290Grace Kloba                    // pauseWebView() taking action.
2143bb0af5ced906e5100d54f0c08e073e669edf2290Grace Kloba                    mPageStarted = false;
21440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
21450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
21460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
21470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21487bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
21497bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2150ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2151ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2152ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2153918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2154918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2155ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2156ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2157918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2158918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21597bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2160918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
21610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
21620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
21630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
21650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
21660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
21670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
21680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
21690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
21700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
21710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
21720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21765942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21775942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
21785942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
21795942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
21805942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
21815942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
21825942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
21835942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21845942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
21855942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = true;
21865942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21875942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
2188da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // WebView/WebTextView handle the keys in the KeyDown. As
2189da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // the Activity's shortcut keys are only handled when WebView
2190da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                // doesn't, have to do it in onKeyDown instead of onKeyUp.
2191da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                if (event.isShiftPressed()) {
2192da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageUp(false);
2193da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                } else {
2194da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                    getTopWindow().pageDown(false);
2195da0fe556a00773ce2af25eb6dcc5442bd08c7addGrace Kloba                }
21965942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
21975942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21985942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
21995942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
22005942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22015942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
22025942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
22035942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
22045942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
22065942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22085942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22115942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
22125942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
22135942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
22145942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
22155942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
22165942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22175942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
22185942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
22195942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
22205942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
22215942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        mWebChromeClient.onHideCustomView();
22225942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
22235942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
22245942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
22250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
22265942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
22275942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
22285942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
22295942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
22305942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
22315942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
22325942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
22335942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
22345942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
22355942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
22360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22375942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22385942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
22395942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22415942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
22420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
224468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
22460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
22480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebViewClient.onPageFinished(w, w.getUrl());
22490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
22520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
22540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // called by a non-UI thread to post the message
22640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void postMessage(int what, int arg1, int arg2, Object obj) {
22650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2, obj));
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
22710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
22730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
22740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CANCEL_CREDS_REQUEST    = 103;
227592c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
22820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
22840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
22850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
22900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
22910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
22940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
22950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
22960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            loadURL(getTopWindow(), url);
22970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
2299c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            final TabControl.Tab parent = mTabControl
2300c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                    .getCurrentTab();
2301c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            final TabControl.Tab newTab = openTab(url);
2302c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2303c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2304c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
23090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
23100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
23110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
231310fdba8a1a4598e7081c150f551c15dbe4a55634Andrei Popescu                            Browser.sendString(BrowserActivity.this, url,
231410fdba8a1a4598e7081c150f551c15dbe4a55634Andrei Popescu                                    getText(R.string.choosertitle_sharevia).toString());
23150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
23170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
23180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
23200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
23220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
23270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    loadURL(getTopWindow(), (String) msg.obj);
23280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
23310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
23320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CANCEL_CREDS_REQUEST:
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    resumeAfterCredentials();
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
23410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
23440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
234789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
234889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
234989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
235089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
235189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
235289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
2353aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
23543918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        ContentResolver cr = getContentResolver();
23553918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        final Cursor c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2356aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                cr, view.getOriginalUrl(), view.getUrl(), true);
23573918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        if (c != null) {
235889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            boolean succeed = c.moveToFirst();
235989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            ContentValues values = null;
236089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            while (succeed) {
236189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                if (values == null) {
236289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    final ByteArrayOutputStream os
236389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            = new ByteArrayOutputStream();
2364dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                    Bitmap bm = createScreenshot(view);
236589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    bm.compress(Bitmap.CompressFormat.PNG, 100, os);
236689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values = new ContentValues();
236789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values.put(Browser.BookmarkColumns.THUMBNAIL,
236889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            os.toByteArray());
236989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
237089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                cr.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
237189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                        c.getInt(0)), values, null, null);
237289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                succeed = c.moveToNext();
237389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
237489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            c.close();
237589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        }
237689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
237789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
237806ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /**
237906ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     * Constants for the size of the thumbnail created when taking a screenshot
238006ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins     */
238106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /* package */ static final int THUMBNAIL_WIDTH = 130;
238206ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins    /* package */ static final int THUMBNAIL_HEIGHT = 104;
238306ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins
2384dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    private Bitmap createScreenshot(WebView view) {
2385dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
238606ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        Bitmap bm = Bitmap.createBitmap(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT,
2387dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                Bitmap.Config.ARGB_4444);
2388dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2389dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2390dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
239106ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        int contentWidth = view.getContentWidth();
239206ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        if (contentWidth > 0) {
239306ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins            float scaleFactor = (float) THUMBNAIL_WIDTH / (float) contentWidth;
239406ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins            canvas.scale(scaleFactor, scaleFactor);
239506ec5f2d8735d1ba17b779deb0f8da032e0a62eaLeon Scroggins        }
2396dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2397dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2398dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2399dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
24000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
24010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebViewClient implementation.
24020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
24030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
24050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
24060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
24070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
24080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
24090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebViewClient getWebViewClient() {
24110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebViewClient;
24120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24143918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott    private void updateIcon(WebView view, Bitmap icon) {
24150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (icon != null) {
24160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
241715525d48024d325c8a52766d8ca727191251a8d4Patrick Scott                    view.getOriginalUrl(), view.getUrl(), icon);
241815525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
241915525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        setFavicon(icon);
242015525d48024d325c8a52766d8ca727191251a8d4Patrick Scott    }
242115525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
242215525d48024d325c8a52766d8ca727191251a8d4Patrick Scott    private void updateIcon(String url, Bitmap icon) {
242315525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        if (icon != null) {
242415525d48024d325c8a52766d8ca727191251a8d4Patrick Scott            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
242515525d48024d325c8a52766d8ca727191251a8d4Patrick Scott                    null, url, icon);
24260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setFavicon(icon);
24280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebViewClient mWebViewClient = new WebViewClient() {
24310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
24320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageStarted(WebView view, String url, Bitmap favicon) {
24330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetLockIcon(url);
243468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(url, null);
2435bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
243659ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            // If we start a touch icon load and then load a new page, we don't
243759ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            // want to cancel the current touch icon loader. But, we do want to
243859ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            // create a new one when the touch icon url is known.
243959ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            if (mTouchIconLoader != null) {
244059ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                mTouchIconLoader.mActivity = null;
244159ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                mTouchIconLoader = null;
244259ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            }
244359ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott
2444bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(false);
2445bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole != null) {
2446bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.clearErrorMessages();
2447bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                if (mShouldShowErrorConsole) {
2448bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                    errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
2449bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                }
2450bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
2451bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
24520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Call updateIcon instead of setFavicon so the bookmark
24530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // database can be updated.
245415525d48024d325c8a52766d8ca727191251a8d4Patrick Scott            updateIcon(url, favicon);
24550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24564d7880fe3061ed691d220e64cd9e54a8c7b2d1bfGrace Kloba            if (mSettings.isTracing()) {
24570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String host;
24580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
24590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebAddress uri = new WebAddress(url);
24600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    host = uri.mHost;
24610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (android.net.ParseException ex) {
24624d7880fe3061ed691d220e64cd9e54a8c7b2d1bfGrace Kloba                    host = "browser";
24630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
24640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                host = host.replace('.', '_');
24654d7880fe3061ed691d220e64cd9e54a8c7b2d1bfGrace Kloba                host += ".trace";
24660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = true;
24674d7880fe3061ed691d220e64cd9e54a8c7b2d1bfGrace Kloba                Debug.startMethodTracing(host, 20 * 1024 * 1024);
24680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
24710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
24720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mStart = SystemClock.uptimeMillis();
24730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mProcessStart = Process.getElapsedCpuTime();
24740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
24750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
24760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
24770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mUserStart = sysCpu[0] + sysCpu[1];
24780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSystemStart = sysCpu[2];
24790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIdleStart = sysCpu[3];
24800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
24810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
24820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mUiStart = SystemClock.currentThreadTimeMillis();
24830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mPageStarted) {
24860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = true;
24877bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // if onResume() has been called, resumeWebViewTimers() does
24887bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // nothing.
24897bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                resumeWebViewTimers();
24900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // reset sync timer to avoid sync starts during loading a page
24930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().resetSync();
24940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mInLoad = true;
2496184f5e351dd511e6dc41ba8468565c14d6beb4f5Leon Scroggins            showFakeTitleBar();
24970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateInLoadMenuItems();
24980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mIsNetworkUp) {
2499eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
25000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (view != null) {
25010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    view.setNetworkAvailable(false);
25020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
25070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageFinished(WebView view, String url) {
25080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Reset the title and icon in case we stopped a provisional
25090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // load.
25100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(view);
2511aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch            updateScreenshot(view);
25120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Update the lock icon image only once we are done loading
25143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            updateLockIconToLatest();
2515b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins
25160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
2517cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project            if (false) {
25180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
25190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
25200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
25210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String uiInfo = "UI thread used "
25220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.currentThreadTimeMillis() - mUiStart)
25230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms";
252431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
25250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, uiInfo);
25260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //The string that gets written to the log
25280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String performanceString = "It took total "
25290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.uptimeMillis() - mStart)
25300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms clock time to load the page."
25310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + "\nbrowser process used "
25320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (Process.getElapsedCpuTime() - mProcessStart)
25330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, user processes used "
25340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
25350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, kernel used "
25360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[2] - mSystemStart) * 10
25370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
25380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms and irq took "
25390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
25400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            * 10 + " ms, " + uiInfo;
254131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
25420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
25430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url != null) {
25450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // strip the url to maintain consistency
25460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String newUrl = new String(url);
25470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (newUrl.startsWith("http://www.")) {
25480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(11);
25490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("http://")) {
25500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(7);
25510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://www.")) {
25520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(12);
25530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://")) {
25540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(8);
25550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
255631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGD_ENABLED) {
25570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.d(LOGTAG, newUrl + " loaded");
25580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
25590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        /*
25600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (sWhiteList.contains(newUrl)) {
25610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // The string that gets pushed to the statistcs
25620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // service
25630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            performanceString = performanceString
25640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nWebpage: "
25650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + newUrl
25660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nCarrier: "
25670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + android.os.SystemProperties
25680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            .get("gsm.sim.operator.alpha");
25690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (mWebView != null
25700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext() != null
25710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext().getSystemService(
25720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Context.CONNECTIVITY_SERVICE) != null) {
25730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                ConnectivityManager cManager =
25740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (ConnectivityManager) mWebView
25750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getContext().getSystemService(
25760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        Context.CONNECTIVITY_SERVICE);
25770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                NetworkInfo nInfo = cManager
25780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getActiveNetworkInfo();
25790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (nInfo != null) {
25800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString = performanceString
25810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + "\nNetwork Type: "
25820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + nInfo.getType().toString();
25830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
25840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
25850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Checkin.logEvent(mResolver,
25860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Checkin.Events.Tag.WEBPAGE_LOAD,
25870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString);
25880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.w(LOGTAG, "pushed to the statistics service");
25890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
25900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        */
25910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             }
25940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mInTrace) {
25960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = false;
25970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Debug.stopMethodTracing();
25980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mPageStarted) {
26010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = false;
26027bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // pauseWebViewTimers() will do nothing and return false if
26037bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // onPause() is not called yet.
26047bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                if (pauseWebViewTimers()) {
26050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
26060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.removeMessages(RELEASE_WAKELOCK);
26070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
26080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // return true if want to hijack the url to let another app to handle it
26140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
26150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideUrlLoading(WebView view, String url) {
26160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith(SCHEME_WTAI)) {
26170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/mc;number
26180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
26190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_MC)) {
26200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent intent = new Intent(Intent.ACTION_VIEW,
26210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Uri.parse(WebView.SCHEME_TEL +
26220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            url.substring(SCHEME_WTAI_MC.length())));
26230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    startActivity(intent);
26240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
26250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/sd;dtmf
26270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // dtmf=string(dialstring)
26280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_SD)) {
26290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
26300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // only send when there is active voice connection
26310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
26320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/ap;number;name
26340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
26350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // name=string
26360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_AP)) {
26370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
26380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
26390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26429918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // The "about:" schemes are internal to the browser; don't
26439918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // want these to be dispatched to other apps.
26449918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            if (url.startsWith("about:")) {
26459918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
26469918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
2647bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
26489918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            Intent intent;
2649bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
26509918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // perform generic parsing of the URI to turn it into an Intent.
26510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
26529918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
26539918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            } catch (URISyntaxException ex) {
26549918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
26550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
26560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26585b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            // check whether the intent can be resolved. If not, we will see
26595b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            // whether we can download it from the Market.
26605b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            if (getPackageManager().resolveActivity(intent, 0) == null) {
26615b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                String packagename = intent.getPackage();
26625b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                if (packagename != null) {
26635b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    intent = new Intent(Intent.ACTION_VIEW, Uri
26645b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                            .parse("market://search?q=pname:" + packagename));
26655b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
26665b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    startActivity(intent);
26675b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    return true;
26685b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                } else {
26695b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    return false;
26705b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                }
26715b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            }
26725b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba
26739918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // sanitize the Intent, ensuring web pages can not bypass browser
26749918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // security (only access to BROWSABLE activities).
26750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.addCategory(Intent.CATEGORY_BROWSABLE);
26769918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            intent.setComponent(null);
26770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
26780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (startActivityIfNeeded(intent, -1)) {
26790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
26800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (ActivityNotFoundException ex) {
26820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // ignore the error. If no application can handle the URL,
26830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // eg about:blank, assume the browser can handle it.
26840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
26870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                openTab(url);
26880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                closeOptionsMenu();
26890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
26900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
26930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
26960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Updates the lock icon. This method is called when we discover another
26970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * resource to be loaded for this page (for example, javascript). While
26980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we update the icon type, we do not update the lock icon itself until
26990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we are done loading, it is slightly more secure this way.
27000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
27010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
27020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onLoadResource(WebView view, String url) {
27030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url != null && url.length() > 0) {
27040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // It is only if the page claims to be secure
27050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // that we may have to update the lock:
27060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mLockIconType == LOCK_ICON_SECURE) {
27070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // If NOT a 'safe' url, change the lock to mixed content!
27080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url) || URLUtil.isAboutUrl(url))) {
27090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mLockIconType = LOCK_ICON_MIXED;
271031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
27110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(LOGTAG, "BrowserActivity.updateLockIcon:" +
27120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                  " updated lock icon to " + mLockIconType + " due to " + url);
27130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
27140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
27200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show the dialog, asking the user if they would like to continue after
27210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * an excessive number of HTTP redirects.
27220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
27230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
27240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onTooManyRedirects(WebView view, final Message cancelMsg,
27250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final Message continueMsg) {
27260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
27270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameRedirect)
27280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrame307Post)
27290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
27300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
27310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        continueMsg.sendToTarget();
27320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
27330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
27340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
27350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
27360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
27370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
27380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
27390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
27400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
27410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
27420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
274437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        // Container class for the next error dialog that needs to be
274537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        // displayed.
274637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        class ErrorDialog {
274737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final int mTitle;
274837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final String mDescription;
274937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final int mError;
275037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            ErrorDialog(int title, String desc, int error) {
275137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mTitle = title;
275237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mDescription = desc;
275337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mError = error;
275437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
275537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        };
275637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
275737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void processNextError() {
275837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors == null) {
275937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                return;
276037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
276137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            // The first one is currently displayed so just remove it.
276237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            mQueuedErrors.removeFirst();
276337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors.size() == 0) {
276437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mQueuedErrors = null;
276537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                return;
276637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
276737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            showError(mQueuedErrors.getFirst());
276837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
276937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
277037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private DialogInterface.OnDismissListener mDialogListener =
277137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                new DialogInterface.OnDismissListener() {
277237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    public void onDismiss(DialogInterface d) {
277337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                        processNextError();
277437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    }
277537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                };
277637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private LinkedList<ErrorDialog> mQueuedErrors;
277737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
277837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void queueError(int err, String desc) {
277937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors == null) {
278037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mQueuedErrors = new LinkedList<ErrorDialog>();
278137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
278237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            for (ErrorDialog d : mQueuedErrors) {
278337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                if (d.mError == err) {
278437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    // Already saw a similar error, ignore the new one.
278537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    return;
278637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                }
278737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
278837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            ErrorDialog errDialog = new ErrorDialog(
27895d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    err == WebViewClient.ERROR_FILE_NOT_FOUND ?
279037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    R.string.browserFrameFileErrorLabel :
279137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    R.string.browserFrameNetworkErrorLabel,
279237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    desc, err);
279337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            mQueuedErrors.addLast(errDialog);
279437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
279537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            // Show the dialog now if the queue was empty.
279637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors.size() == 1) {
279737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                showError(errDialog);
279837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
279937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
280037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
280137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void showError(ErrorDialog errDialog) {
280237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            AlertDialog d = new AlertDialog.Builder(BrowserActivity.this)
280337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setTitle(errDialog.mTitle)
280437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setMessage(errDialog.mDescription)
280537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setPositiveButton(R.string.ok, null)
280637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .create();
280737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            d.setOnDismissListener(mDialogListener);
280837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            d.show();
280937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
281037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
28110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
28120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show a dialog informing the user of the network error reported by
28130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * WebCore.
28140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
28150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
28160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedError(WebView view, int errorCode,
28170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String description, String failingUrl) {
28185d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
28195d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    errorCode != WebViewClient.ERROR_CONNECT &&
28205d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    errorCode != WebViewClient.ERROR_BAD_URL &&
28215d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
28225d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    errorCode != WebViewClient.ERROR_FILE) {
282337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                queueError(errorCode, description);
28240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
282537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
282637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    + " " + description);
28270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2828aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                mNeedExtraScreenShot = true;
2829aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
28300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We need to reset the title after an error.
28310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndRevertLockIcon();
28320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
28350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Check with the user if it is ok to resend POST data as the page they
28360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * are trying to navigate to is the result of a POST.
28370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
28380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
28390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onFormResubmission(WebView view, final Message dontResend,
28400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                       final Message resend) {
28410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
28420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameFormResubmitLabel)
28430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrameFormResubmitMessage)
28440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
28450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
28460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        resend.sendToTarget();
28470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
28480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
28490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
28500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
28510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
28520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
28530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
28540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
28550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
28560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
28570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
28600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Insert the url into the visited history database.
28610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param url The url to be inserted.
28620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param isReload True if this url is being reloaded.
28630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * FIXME: Not sure what to do when reloading the page.
28640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
28650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
28660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void doUpdateVisitedHistory(WebView view, String url,
28670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isReload) {
28680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.regionMatches(true, 0, "about:", 0, 6)) {
28690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
28700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28716b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            // remove "client" before updating it to the history so that it wont
28726b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            // show up in the auto-complete list.
28736b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            int index = url.indexOf("client=ms-");
28746b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            if (index > 0 && url.contains(".google.")) {
28756b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                int end = url.indexOf('&', index);
28766b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                if (end > 0) {
28776b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                    url = url.substring(0, index-1).concat(url.substring(end));
28786b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                } else {
28796b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                    url = url.substring(0, index-1);
28806b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                }
28816b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            }
28820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Browser.updateVisitedHistory(mResolver, url, true);
28830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebIconDatabase.getInstance().retainIconForPageUrl(url);
28840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
28870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Displays SSL error(s) dialog to the user.
28880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
28890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedSslError(
28910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final WebView view, final SslErrorHandler handler, final SslError error) {
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSettings.showSecurityWarnings()) {
28940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LayoutInflater factory =
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LayoutInflater.from(BrowserActivity.this);
28960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final View warningsView =
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    factory.inflate(R.layout.ssl_warnings, null);
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LinearLayout placeholder =
28990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
29000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_UNTRUSTED)) {
29020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
29030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
29040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
29050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_untrusted);
29060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
29070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_IDMISMATCH)) {
29100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
29110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
29120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
29130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_mismatch);
29140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
29150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_EXPIRED)) {
29180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
29190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
29200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
29210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_expired);
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_NOTYETVALID)) {
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
29290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_not_yet_valid);
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.security_warning)
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setView(warningsView)
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.ssl_continue,
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
29400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.proceed();
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNeutralButton(R.string.view_certificate,
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
29450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
29460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    showSSLCertificateOnError(view, handler, error);
29470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
29490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.cancel,
29500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
29510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
29520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
29540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
29550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setOnCancelListener(
29570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnCancelListener() {
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onCancel(DialogInterface dialog) {
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
29620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .show();
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed();
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Handles an HTTP authentication request.
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param handler The authentication handler
29730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param host The host
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param realm The realm
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedHttpAuthRequest(WebView view,
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final HttpAuthHandler handler, final String host, final String realm) {
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String username = null;
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = null;
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean reuseHttpAuthUsernamePassword =
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.useHttpAuthUsernamePassword();
29840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (reuseHttpAuthUsernamePassword &&
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (mTabControl.getCurrentWebView() != null)) {
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String[] credentials =
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getCurrentWebView()
29890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .getHttpAuthUsernamePassword(host, realm);
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (credentials != null && credentials.length == 2) {
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    username = credentials[0];
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    password = credentials[1];
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (username != null && password != null) {
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed(username, password);
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showHttpAuthentication(handler, host, realm, null, null, null, 0);
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
30050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
30060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only check shortcut key when MENU is held
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return getWindow().isShortcutKey(event.getKeyCode(), event);
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (view != mTabControl.getCurrentTopWebView()) {
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (event.isDown()) {
30190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyDown(event.getKeyCode(), event);
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyUp(event.getKeyCode(), event);
30220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
30250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
30270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebChromeClient implementation
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebChromeClient getWebChromeClient() {
30310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebChromeClient;
30320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
30350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Helper method to create a new tab or sub window.
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private void createWindow(final boolean dialog, final Message msg) {
30370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog) {
30380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabControl.createSubWindow();
30390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab t = mTabControl.getCurrentTab();
30400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                attachSubWindow(t);
30410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
30420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
30430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(t.getSubWebView());
30440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg.sendToTarget();
30450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
30460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab parent = mTabControl.getCurrentTab();
30471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                final TabControl.Tab newTab
30481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        = openTabAndShow(EMPTY_URL_DATA, false, null);
3049c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                if (newTab != parent) {
3050c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                    parent.addChildTab(newTab);
3051c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                }
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
30540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(mTabControl.getCurrentWebView());
30551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                msg.sendToTarget();
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onCreateWindow(WebView view, final boolean dialog,
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final boolean userGesture, final Message resultMsg) {
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if we can't create any more tabs or sub windows.
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog && mTabControl.getCurrentSubWindow() != null) {
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_subwindows_dialog_title)
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_subwindows_dialog_message)
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (mTabControl.getTabCount() >= TabControl.MAX_TABS) {
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_windows_dialog_title)
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_windows_dialog_message)
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if this was a user gesture.
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (userGesture) {
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                createWindow(dialog, resultMsg);
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
30850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Allow the popup and create the appropriate window.
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener allowListener =
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d,
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                int which) {
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            createWindow(dialog, resultMsg);
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Block the popup by returning a null WebView.
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener blockListener =
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d, int which) {
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            resultMsg.sendToTarget();
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Build a confirmation dialog to display to the user.
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog d =
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.Builder(BrowserActivity.this)
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.attention)
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setMessage(R.string.popup_window_attempt)
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.allow, allowListener)
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.block, blockListener)
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setCancelable(false)
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .create();
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Show the confirmation dialog.
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d.show();
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onCloseWindow(WebView window) {
31221f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            final TabControl.Tab current = mTabControl.getCurrentTab();
31231f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            final TabControl.Tab parent = current.getParentTab();
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // JavaScript can only close popup window.
31261f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
31271f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we need to close the window
31281f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onProgressChanged(WebView view, int newProgress) {
313468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            mTitleBar.setProgress(newProgress);
31353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mFakeTitleBar != null) {
31363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mFakeTitleBar.setProgress(newProgress);
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (newProgress == 100) {
3140aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                // onProgressChanged() may continue to be called after the main
3141aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                // frame has finished loading, as any remaining sub frames
3142aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                // continue to load. We'll only get called once though with
3143aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                // newProgress as 100 when everything is loaded.
3144aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                // (onPageFinished is called once when the main frame completes
3145aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                // loading regardless of the state of any sub frames so calls
3146aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                // to onProgressChanges may continue after onPageFinished has
3147aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                // executed)
3148aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
3149aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                // sync cookies and cache promptly here.
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CookieSyncManager.getInstance().sync();
3151cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                if (mInLoad) {
3152cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    mInLoad = false;
3153cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    updateInLoadMenuItems();
3154a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    // If the options menu is open, leave the title bar
3155a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    if (!mOptionsMenuOpen || !mIconView) {
3156a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                        hideFakeTitleBar();
3157a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    }
3158cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
3159aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                if (mNeedExtraScreenShot) {
3160aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                    // if there was an error loading this page, capture a new
3161aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                    // screenshot to ensure that we get the correct thumbnail
3162aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                    // as onPageFinished may have been called before the error
3163aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                    // page was displayed.
3164aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                    updateScreenshot(view);
3165aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                    mNeedExtraScreenShot = false;
3166aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch                }
3167a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            } else if (!mInLoad) {
3168cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // onPageFinished may have already been called but a subframe
3169cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // is still loading and updating the progress. Reset mInLoad
3170cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // and update the menu items.
3171a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                mInLoad = true;
3172a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
3173184f5e351dd511e6dc41ba8468565c14d6beb4f5Leon Scroggins                if (!mOptionsMenuOpen || mIconView) {
3174a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    // This page has begun to load, so show the title bar
3175a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    showFakeTitleBar();
3176cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedTitle(WebView view, String title) {
3182598c9ccf8641e0e4563bba2fd5613bcb4de766ecPatrick Scott            String url = view.getUrl();
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // here, if url is null, we want to reset the title
318568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(url, title);
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url == null ||
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url.length() >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3191fce182bff7713a12714018327f6da9500011ab17Leon Scroggins            // See if we can find the current url in our history database and
3192fce182bff7713a12714018327f6da9500011ab17Leon Scroggins            // add the new title to it.
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith("http://www.")) {
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(11);
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (url.startsWith("http://")) {
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(4);
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = "%" + url;
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String [] selArgs = new String[] { url };
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String where = Browser.BookmarkColumns.URL + " LIKE ? AND "
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + Browser.BookmarkColumns.BOOKMARK + " = 0";
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Browser.HISTORY_PROJECTION, where, selArgs, null);
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (c.moveToFirst()) {
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Current implementation of database only has one entry per
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // url.
3209fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    ContentValues map = new ContentValues();
3210fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    map.put(Browser.BookmarkColumns.TITLE, title);
3211fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    mResolver.update(Browser.BOOKMARKS_URI, map,
3212fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                            "_id = " + c.getInt(0), null);
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.close();
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IllegalStateException e) {
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "BrowserActivity onReceived title", e);
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (SQLiteException ex) {
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "onReceivedTitle() caught SQLiteException: ", ex);
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
32230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedIcon(WebView view, Bitmap icon) {
32243918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            updateIcon(view, icon);
32253918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        }
32263918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott
32273918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        @Override
322859ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott        public void onReceivedTouchIconUrl(WebView view, String url,
322959ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                boolean precomposed) {
32303918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            final ContentResolver cr = getContentResolver();
32313918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            final Cursor c =
32323918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                    BrowserBookmarksAdapter.queryBookmarksForUrl(cr,
3233a5d669e4c08f0e64387c2c539c41a26ac8c845abLeon Scroggins                            view.getOriginalUrl(), view.getUrl(), true);
32343918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            if (c != null) {
32353918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                if (c.getCount() > 0) {
323659ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    // Let precomposed icons take precedence over non-composed
323759ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    // icons.
323859ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    if (precomposed && mTouchIconLoader != null) {
323959ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                        mTouchIconLoader.cancel(false);
324059ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                        mTouchIconLoader = null;
324159ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    }
324259ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    // Have only one async task at a time.
324359ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    if (mTouchIconLoader == null) {
324459ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                        mTouchIconLoader = new DownloadTouchIcon(
324559ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                                BrowserActivity.this, cr, c, view);
324659ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                        mTouchIconLoader.execute(url);
324759ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    }
32483918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                } else {
32493918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                    c.close();
32503918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                }
32513918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3253092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
3254adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        @Override
3255c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu        public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
3256adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            if (mCustomView != null)
3257adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                return;
3258adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3259adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Add the custom view to its container.
3260adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
3261adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomView = view;
3262c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomViewCallback = callback;
3263adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Save the menu state and set it to empty while the custom
3264adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // view is showing.
3265adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mOldMenuState = mMenuState;
3266adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mMenuState = EMPTY_MENU;
3267c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            // Hide the content view.
3268c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mContentView.setVisibility(View.GONE);
3269adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Finally show the custom view container.
3270c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomViewContainer.setVisibility(View.VISIBLE);
3271c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomViewContainer.bringToFront();
3272adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        }
3273adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3274adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        @Override
3275adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        public void onHideCustomView() {
3276adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            if (mCustomView == null)
3277adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                return;
3278adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3279c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            // Hide the custom view.
3280c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomView.setVisibility(View.GONE);
3281adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Remove the custom view from its container.
3282adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer.removeView(mCustomView);
3283adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomView = null;
3284adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Reset the old menu state.
3285adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mMenuState = mOldMenuState;
3286adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mOldMenuState = EMPTY_MENU;
3287adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer.setVisibility(View.GONE);
3288c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomViewCallback.onCustomViewHidden();
3289c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            // Show the content view.
3290c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mContentView.setVisibility(View.VISIBLE);
3291adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        }
3292adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3293092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        /**
329479e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * The origin has exceeded its database quota.
3295092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param url the URL that exceeded the quota
3296092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param databaseIdentifier the identifier of the database on
3297092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         *     which the transaction that caused the quota overflow was run
3298092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param currentQuota the current quota for the origin.
329925a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch         * @param estimatedSize the estimated size of the database.
330079e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * @param totalUsedQuota is the sum of all origins' quota.
3301092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param quotaUpdater The callback to run when a decision to allow or
3302092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         *     deny quota has been made. Don't forget to call this!
3303092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         */
3304092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        @Override
3305092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        public void onExceededDatabaseQuota(String url,
330625a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch            String databaseIdentifier, long currentQuota, long estimatedSize,
330725a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
330879e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu            mSettings.getWebStorageSizeManager().onExceededDatabaseQuota(
330925a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch                    url, databaseIdentifier, currentQuota, estimatedSize,
331025a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch                    totalUsedQuota, quotaUpdater);
331179e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu        }
331279e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu
331379e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu        /**
331479e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * The Application Cache has exceeded its max size.
331579e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * @param spaceNeeded is the amount of disk space that would be needed
331679e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * in order for the last appcache operation to succeed.
331779e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * @param totalUsedQuota is the sum of all origins' quota.
331879e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * @param quotaUpdater A callback to inform the WebCore thread that a new
331979e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * app cache size is available. This callback must always be executed at
332079e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * some point to ensure that the sleeping WebCore thread is woken up.
332179e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         */
332279e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu        @Override
332379e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu        public void onReachedMaxAppCacheSize(long spaceNeeded,
332479e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
332579e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu            mSettings.getWebStorageSizeManager().onReachedMaxAppCacheSize(
332679e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu                    spaceNeeded, totalUsedQuota, quotaUpdater);
3327092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        }
33287db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch
33292bc69918d97a767a02132090e58718077381ba1aSteve Block        /**
33302bc69918d97a767a02132090e58718077381ba1aSteve Block         * Instructs the browser to show a prompt to ask the user to set the
33312bc69918d97a767a02132090e58718077381ba1aSteve Block         * Geolocation permission state for the specified origin.
33322bc69918d97a767a02132090e58718077381ba1aSteve Block         * @param origin The origin for which Geolocation permissions are
33332bc69918d97a767a02132090e58718077381ba1aSteve Block         *     requested.
33342bc69918d97a767a02132090e58718077381ba1aSteve Block         * @param callback The callback to call once the user has set the
33352bc69918d97a767a02132090e58718077381ba1aSteve Block         *     Geolocation permission state.
33362bc69918d97a767a02132090e58718077381ba1aSteve Block         */
33372bc69918d97a767a02132090e58718077381ba1aSteve Block        @Override
33382bc69918d97a767a02132090e58718077381ba1aSteve Block        public void onGeolocationPermissionsShowPrompt(String origin,
33392bc69918d97a767a02132090e58718077381ba1aSteve Block                GeolocationPermissions.Callback callback) {
33402bc69918d97a767a02132090e58718077381ba1aSteve Block            mTabControl.getCurrentTab().getGeolocationPermissionsPrompt().show(
33412bc69918d97a767a02132090e58718077381ba1aSteve Block                    origin, callback);
33422bc69918d97a767a02132090e58718077381ba1aSteve Block        }
33432bc69918d97a767a02132090e58718077381ba1aSteve Block
33442bc69918d97a767a02132090e58718077381ba1aSteve Block        /**
33452bc69918d97a767a02132090e58718077381ba1aSteve Block         * Instructs the browser to hide the Geolocation permissions prompt.
33462bc69918d97a767a02132090e58718077381ba1aSteve Block         */
33472bc69918d97a767a02132090e58718077381ba1aSteve Block        @Override
33482bc69918d97a767a02132090e58718077381ba1aSteve Block        public void onGeolocationPermissionsHidePrompt() {
33492bc69918d97a767a02132090e58718077381ba1aSteve Block            mTabControl.getCurrentTab().getGeolocationPermissionsPrompt().hide();
33502bc69918d97a767a02132090e58718077381ba1aSteve Block        }
33512bc69918d97a767a02132090e58718077381ba1aSteve Block
33527db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        /* Adds a JavaScript error message to the system log.
33537db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param message The error message to report.
33547db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param lineNumber The line number of the error.
33557db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param sourceID The name of the source file that caused the error.
33567db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         */
33577db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        @Override
33587db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        public void addMessageToConsole(String message, int lineNumber, String sourceID) {
3359bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(true);
3360bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            errorConsole.addErrorMessage(message, sourceID, lineNumber);
3361bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                if (mShouldShowErrorConsole &&
3362bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                        errorConsole.getShowState() != ErrorConsoleView.SHOW_MAXIMIZED) {
3363bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
3364bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                }
3365bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            Log.w(LOGTAG, "Console: " + message + " " + sourceID + ":" + lineNumber);
33667db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        }
3367540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
3368540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        /**
3369540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * Ask the browser for an icon to represent a <video> element.
3370540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * This icon will be used if the Web page did not specify a poster attribute.
3371540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         *
3372540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * @return Bitmap The icon or null if no such icon is available.
3373540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * @hide pending API Council approval
3374540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         */
3375540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        @Override
3376540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        public Bitmap getDefaultVideoPoster() {
3377540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            if (mDefaultVideoPoster == null) {
3378540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu                mDefaultVideoPoster = BitmapFactory.decodeResource(
3379540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu                        getResources(), R.drawable.default_video_poster);
3380540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            }
3381540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            return mDefaultVideoPoster;
3382540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
3383540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
3384540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        /**
3385540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * Ask the host application for a custom progress view to show while
3386540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * a <video> is loading.
3387540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         *
3388540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * @return View The progress view.
3389540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * @hide pending API Council approval
3390540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         */
3391540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        @Override
3392540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        public View getVideoLoadingProgressView() {
3393540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            if (mVideoProgressView == null) {
3394540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu                LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
3395540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu                mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
3396540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            }
3397540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            return mVideoProgressView;
3398540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
3415e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
3416e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
3421e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
3422e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
3423e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
3424e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
3425e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
3426e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
3427e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
3428e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
3429e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
3430e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
3431e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
3432e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
3433e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
3434e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
3435e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
3436e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
3437e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
3438e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
3439e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
3440e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
3441e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
3442e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
3443e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // java.net.URI is a lot stricter than KURL so we have to undo
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // KURL's percent-encoding and redo the encoding using java.net.URI.
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        URI uri = null;
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Undo the percent-encoding that KURL may have done.
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String newUrl = new String(URLUtil.decode(url.getBytes()));
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Parse the url into pieces
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebAddress w = new WebAddress(newUrl);
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String frag = null;
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String query = null;
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String path = w.mPath;
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Break the path into path, query, and fragment
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (path.length() > 0) {
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Strip the fragment
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int idx = path.lastIndexOf('#');
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    frag = path.substring(idx + 1);
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                idx = path.lastIndexOf('?');
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query = path.substring(idx + 1);
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
35140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query, frag);
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
35273dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_URI, uri.toString());
35283dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_COOKIE_DATA, cookies);
35293dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_USER_AGENT, userAgent);
35303dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_NOTIFICATION_PACKAGE,
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
35323dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_NOTIFICATION_CLASS,
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class.getCanonicalName());
35343dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_VISIBILITY, Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
35353dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_MIME_TYPE, mimetype);
35363dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_FILE_NAME_HINT, filename);
35373dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_DESCRIPTION, uri.getHost());
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
35393dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru            values.put(Downloads.COLUMN_TOTAL_BYTES, contentLength);
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
35460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
35470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getContentResolver().insert(Downloads.CONTENT_URI, values);
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            viewDownloads(contentUri);
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        saveLockIcon();
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = LOCK_ICON_UNSECURE;
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (URLUtil.isHttpsUrl(url)) {
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mLockIconType = LOCK_ICON_SECURE;
356431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                      " reset lock icon to " + mLockIconType);
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3573eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    /* package */ void setLockIconType(int type) {
3574eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        mLockIconType = type;
3575eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    }
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3577eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    /* package */ int getLockIconType() {
3578eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        return mLockIconType;
3579eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    }
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3581eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    /* package */ void setPrevLockType(int type) {
3582eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        mPrevLockType = type;
3583eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    }
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3585eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    /* package */ int getPrevLockType() {
3586eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        return mPrevLockType;
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
35913bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
35923bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /* package */ void updateLockIconToLatest() {
35933bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        updateLockIconImage(mLockIconType);
35943bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
35953bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
35963bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
36000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
360668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
36073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (mFakeTitleBar != null) {
36083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setLock(d);
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showPageInfo(final TabControl.Tab tab,
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
36240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
36260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
36370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoFromShowSSLCertificateOnError = new Boolean(fromShowSSLCertificateOnError);
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
36810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
37000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
37010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
37020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
37070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
37080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
37090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
37100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
37110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
37130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
37140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
37150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
37160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
37170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
37180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
37190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
37200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
37210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
37220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
37230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
37240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
37260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
37270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
37360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
37370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificate(final TabControl.Tab tab) {
37390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
37420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
37460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
37480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
37490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
37510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
37520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
37530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
37540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
37560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
37570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
37580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
37590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
37600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
37610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
37620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
37630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
37640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
37650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
37660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
37670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
37690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
37700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
37710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
37720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
37730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
37740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
37750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
37760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
37780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
37790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
37800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
37810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
37850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
37860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
37870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
37880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
37890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificateOnError(
37910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
37920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
37940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
37950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
37960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
37970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
38000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
38020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
38030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
38050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
38060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
38070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
38090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
38130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
38140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
38150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
38160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
38210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
38300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
38340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
38400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
38410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
38420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
38430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
38450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
38560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
38600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
38610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
38950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
38970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
39220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String issuedOn = reformatCertificateDate(
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotBefore());
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
39280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String expiresOn = reformatCertificateDate(
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotAfter());
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Re-formats the certificate date (Date.toString()) string to
39380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * a properly localized date string.
39390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
39400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the original certificate date string if fails to localize.
39410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the original string is null, returns an empty string "".
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String reformatCertificateDate(String certificateDate) {
39440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      String reformattedDate = null;
39450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if (certificateDate != null) {
39470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Date date = null;
39480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
39490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = java.text.DateFormat.getInstance().parse(certificateDate);
39500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (ParseException e) {
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = null;
39520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
39530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (date != null) {
39550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              reformattedDate =
39560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  DateFormat.getDateFormat(this).format(date);
39570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
39580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
39590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return reformattedDate != null ? reformattedDate :
39610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          (certificateDate != null ? certificateDate : "");
39620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
39650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
39660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showHttpAuthentication(final HttpAuthHandler handler,
39680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
39690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
39700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
39710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
39720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
39730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
39740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
39750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
39770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
39780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
39810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
39820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
39830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
39840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
39870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
39880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
39890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
39900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
39910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
39920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
39930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
39940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
39950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
39960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
39970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
39980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
39990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
40000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
40010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
40020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
40030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
40040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
40050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
40060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
40070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
40080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
40090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
40100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
40110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
40120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
40130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
40140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
40150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
40160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
40170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
40180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
40190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
40200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
40210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
40220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
40230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
40240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
40250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
40260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
40270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
40280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
40290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
40300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
40310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
40320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
40340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
40370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
40380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
40390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
40400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
40410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
40420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
40470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
40480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
40490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
40500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
40510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
40520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
40530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
40550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
40560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
40570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
40580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
40590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
40600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
40650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
40660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
40680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
40690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
40700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
40710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
40720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
40730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
40740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
40750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
40760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
40770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
4078eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
4079eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
4080eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
40810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
40830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
40840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
40850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4088eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
4089eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
4090eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
4091eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
4092eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
4093eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
4094eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
4095eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
4096eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
4097eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
4098eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
4099eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
41000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
41010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
41020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
41030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
41040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
41050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
41060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
41070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
41080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
410925d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
41100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
41110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final TabControl.Tab currentTab =
41120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
41131f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
41141f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
41151f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            getTopWindow().loadUrl(data);
41160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
41170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
41180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
41190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
41200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
41210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
41220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4123304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
41240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
41270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
41280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * menu to see the download window, or when a download changes state. It
41290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * shows the download window ontop of the current window.
41300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
41310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void viewDownloads(Uri downloadRecord) {
41320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
41330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
41340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
41350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, this.DOWNLOAD_PAGE);
41360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4139160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
4140160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
4141160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
4142160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
4143160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
4144304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
41450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
41460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
41470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
41480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
41500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
41510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
41520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
4153dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap thumbnail = createScreenshot(current);
4154dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
41550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
41560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
41570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
41580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
41590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
41600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
41610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
41620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
41630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
41650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
41660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
41670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
41690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
4170dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
4171304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
4172304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        intent.putExtra("disable_new_window", mTabControl.getTabCount()
4173304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                >= TabControl.MAX_TABS);
41743918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
41750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
41760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
41770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
41780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
41800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
41830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void loadURL(WebView view, String url) {
41840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
41850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
41860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
41870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mWebViewClient.shouldOverrideUrlLoading(view, url)) {
41880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                view.loadUrl(url);
41890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
41900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
41940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
41950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
41960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
41980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get window count
42020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    int getWindowCount(){
42040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if(mTabControl != null){
42050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getTabCount();
42060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
42070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return 0;
42080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4210b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
42110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
42120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
42130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
421425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
42150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
42160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
42170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
42190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
42200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
42210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
42220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
42230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
42240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
42250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
42260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
42270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
42280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
42290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
42310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
42320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
42340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
42350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
42360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
42370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
42380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
4239123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
4240123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
4241123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
4242123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
42430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
42440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
42450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
4247565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
4248565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
4249565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
4250565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
4251565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
4252565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
4253565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
4254565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
425547fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
4256565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
4257565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
4258565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
4259565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
4260565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
42610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
4262565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
42630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
42640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
42650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
42660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Regex.WEB_URL_PATTERN.matcher(inUrl).matches()) {
42670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
42680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
42690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
427247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
42730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4275bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
4276bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
4277bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
4278bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
4279bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
4280bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4281bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
4282bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4283bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(true);
4284bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4285bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
4286bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
4287bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
4288bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
4289bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
4290bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
4291bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
4292bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4293bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
4294bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
4295bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
4296bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
4297bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
4298bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
4299bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
4300bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4301bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
4302bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4303eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
4304eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
4305eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
43060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mLockIconType = LOCK_ICON_UNSECURE;
43080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mPrevLockType = LOCK_ICON_UNSECURE;
43090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
43110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
43120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
43130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
4314adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
4315adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
4316c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
43170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
43190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
43200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
43210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
4322adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
43230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
43240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
43250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
43270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
43280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
43290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
43300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
43320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
43330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mPageStarted;
43350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mActivityInPause = true;
43360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4337aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch    // If the frame fails to load, we should snap a second screenshot
4338aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch    // to ensure that we get the right thumbnail (i.e. of the error page).
4339aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch    private boolean mNeedExtraScreenShot = false;
4340aac7aa6fcfcb519755987ec126be066323f589c8Ben Murdoch
43410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
43420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
43440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
43460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
43470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
43480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
43490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
43500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
43510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
43520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
43530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
43540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
43550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
43560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
43580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
43590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
43600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
43610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
43620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
43630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
43650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
43670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
43680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
43700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
43710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wait for credentials before loading google.com
43730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ProgressDialog mCredsDlg;
43740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
43760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
43770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
43780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
43790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
43800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
43820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
43830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
43840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mPageInfoView;
43850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
43860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
43870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
43880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Boolean mPageInfoFromShowSSLCertificateOnError;
43890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
43910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
43920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
43930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
43940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
43950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
43960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
43980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
43990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
44000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mSSLCertificateView;
44010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
44030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
44040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
44050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
44060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
44080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
44090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT,
44100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT);
4411adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
4412adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
4413adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            ViewGroup.LayoutParams.FILL_PARENT,
4414adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            ViewGroup.LayoutParams.FILL_PARENT,
4415adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
441647fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
441747fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
44180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
44190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
44200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
44210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
44220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
44230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
44240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
44260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
44280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
44290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
44300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
44310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
44320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
44330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
44340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
44350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
44360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
44370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
44390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
44410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
44430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
44440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
44460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
444768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private TitleBar mTitleBar;
444881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
4449bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
4450bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
4451bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
44520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
44530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
44540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
44550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
44560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
44570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
44580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
44600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
44610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
44620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4463b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
4464b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
446559ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott    // AsyncTask for downloading touch icons
446659ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott    /* package */ DownloadTouchIcon mTouchIconLoader;
446759ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott
44680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
446978a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
447078a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
447178a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
44720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4473540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
4474540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
4475540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
4476540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
4477540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
447825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
447925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
448025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
448125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
448225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class UrlData {
448325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mUrl;
448460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        byte[] mPostData;
448560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
448625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
448725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
448825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
448960e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
449060e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        void setPostData(byte[] postData) {
449160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            mPostData = postData;
449260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
449360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
449425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
449525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            return mUrl == null || mUrl.length() == 0;
449625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
449725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
44987944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        public void loadIn(WebView webView) {
449960e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            if (mPostData != null) {
450060e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                webView.postUrl(mUrl, mPostData);
450160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            } else {
450260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                webView.loadUrl(mUrl);
450360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            }
450425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
450525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
450625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
450725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
450825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A subclass of UrlData class that can display inlined content using
450925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * {@link WebView#loadDataWithBaseURL(String, String, String, String, String)}.
451025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
451125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class InlinedUrlData extends UrlData {
451225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        InlinedUrlData(String inlined, String mimeType, String encoding, String failUrl) {
451325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            super(failUrl);
451425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mInlined = inlined;
451525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mMimeType = mimeType;
451625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mEncoding = encoding;
451725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
451825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mMimeType;
451925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mInlined;
452025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mEncoding;
45217944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        @Override
452225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
4523bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return mInlined == null || mInlined.length() == 0 || super.isEmpty();
452425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
452525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
45267944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        @Override
45277944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        public void loadIn(WebView webView) {
452825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            webView.loadDataWithBaseURL(null, mInlined, mMimeType, mEncoding, mUrl);
452925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
453025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    }
453125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
45321f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
45330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
4534