BrowserActivity.java revision a5bf1deca120315a2643ea5b010f94d853461b15
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
3080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
3090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // start MASF proxy service
3100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
3110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
3120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
3130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //    (new ComponentName(
3140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
3150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
3160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //startService(proxyServiceIntent, null);
3170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
3190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
3200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
3210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
3220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
32481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
3253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(this)
3263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .inflate(R.layout.custom_screen, null);
3273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(
3283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                R.id.main_content);
3293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mErrorConsoleContainer = (LinearLayout) mBrowserFrameLayout
3303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.error_console);
3313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout
3323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                .findViewById(R.id.fullscreen_custom_content);
3333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        frameLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);
33468579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar = new TitleBar(this);
3350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
3370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
3380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
3400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
3410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
3430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
3440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
3450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.loadFromDb(this);
3460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
3480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
3490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
350a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        /* enables registration for changes in network status from
351a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba           http stack */
352a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter = new IntentFilter();
353a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateChangedFilter.addAction(
354a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                ConnectivityManager.CONNECTIVITY_ACTION);
355a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba        mNetworkStateIntentReceiver = new BroadcastReceiver() {
356a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                @Override
357a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                public void onReceive(Context context, Intent intent) {
358a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    if (intent.getAction().equals(
359a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                            ConnectivityManager.CONNECTIVITY_ACTION)) {
360eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                        NetworkInfo info =
361eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                                (NetworkInfo) intent.getParcelableExtra(
362eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                                        ConnectivityManager.EXTRA_NETWORK_INFO);
363eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                        onNetworkToggle(
364eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                                (info != null) ? info.isConnected() : false);
365a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                    }
366a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba                }
367a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba            };
368a34f686112fb4f9fbea00b8c2c47153d34e93e41Grace Kloba
369615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
370615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
371615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        filter.addDataScheme("package");
372615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
373615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            @Override
374615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            public void onReceive(Context context, Intent intent) {
375615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String action = intent.getAction();
376615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final String packageName = intent.getData()
377615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        .getSchemeSpecificPart();
378615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                final boolean replacing = intent.getBooleanExtra(
379615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        Intent.EXTRA_REPLACING, false);
380615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
381615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    // if it is replacing, refreshPlugins() when adding
382615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
383615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
384615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
385615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                PackageInfo pkgInfo = null;
386615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                try {
387615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
388615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            PackageManager.GET_PERMISSIONS);
389615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
390615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    return;
391615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
392615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                if (pkgInfo != null) {
393615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
394615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissions == null) {
395615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        return;
396615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
397615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    boolean permissionOk = false;
398615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    for (String permit : permissions) {
399615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
400615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            permissionOk = true;
401615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                            break;
402615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        }
403615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
404615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    if (permissionOk) {
405615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
406615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                .refreshPlugins(
407615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
408615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                                                .equals(action));
409615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                    }
410615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba                }
411615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba            }
412615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        };
413615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
414615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
415565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // If this was a web search request, pass it on to the default web search provider.
416565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (handleWebSearchIntent(getIntent())) {
417565505b1a2c1d3099496af5910760087602e994aSatish Sampath            moveTaskToBack(true);
418565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return;
419565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
420565505b1a2c1d3099496af5910760087602e994aSatish Sampath
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
4230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
426aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // there is no quit on Android. But if we can't restore the state,
427aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            // we can treat it as a new Browser, remove the old session cookies.
428aab3f09b5c2d39b19067e57635614080b2403a46Grace Kloba            CookieManager.getInstance().removeSessionCookie();
4290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
4300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
4310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
43525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
43625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
4370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab t = mTabControl.createNewTab(
4380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent.ACTION_VIEW.equals(intent.getAction()) &&
439f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    intent.getData() != null,
44025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
4410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
4420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
4430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
4440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
4450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
4460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
4470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
4480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
4490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we are not restoring from an icicle, then there is a high
4510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // likely hood this is the first run. So, check to see if the
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // homepage needs to be configured and copy any plugins from our
4530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // asset directory to the data partition.
4540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((extra == null || !extra.getBoolean("testing"))
4550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    && !mSettings.isLoginInitialized()) {
4560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                setupHomePage();
4570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
460304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                if (mSettings.isLoginInitialized()) {
461304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    webView.loadUrl(mSettings.getHomePage());
462304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                } else {
463304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                    waitForCredentials();
464304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                }
4650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
46681678d9216458266ea70cd62d52f28f744873556Grace Kloba                if (extra != null) {
46781678d9216458266ea70cd62d52f28f744873556Grace Kloba                    urlData.setPostData(extra
46881678d9216458266ea70cd62d52f28f744873556Grace Kloba                            .getByteArray(Browser.EXTRA_POST_DATA));
46981678d9216458266ea70cd62d52f28f744873556Grace Kloba                }
47025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData.loadIn(webView);
4710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
4730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
4741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // restoring the state fails.
4750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
4760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
477615c6c9130a1bd21c63cd37d09f8f4ea3229ca13Grace Kloba
478b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
479b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
480b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
481b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
482b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
4830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
4840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
4860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
4870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
4880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
4890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
4900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
4910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
4920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
4930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
4940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
4950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
4960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
4980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
4990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
5000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
5020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
5030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
5040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
5050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
5060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
5070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
5090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
5100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
5110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_WEB_SEARCH.equals(action)) {
512565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
513565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
514565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
515565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
516565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
517565505b1a2c1d3099496af5910760087602e994aSatish Sampath
51825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
51925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
52025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
5210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
52281678d9216458266ea70cd62d52f28f744873556Grace Kloba            urlData.setPostData(intent
52381678d9216458266ea70cd62d52f28f744873556Grace Kloba                    .getByteArrayExtra(Browser.EXTRA_POST_DATA));
52425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
525cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
526cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
527cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            if (Intent.ACTION_VIEW.equals(action)
528cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
529cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
530cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                TabControl.Tab appTab = mTabControl.getTabFromId(appId);
531f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
532f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
533f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
534f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
535f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
536f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
537f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
538f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
539f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
540f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
541f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
54225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            mTabControl.recreateWebView(appTab, urlData.mUrl);
543bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
544f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
5451f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        switchToTab(mTabControl.getTabIndex(appTab));
5461f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            urlData.loadIn(appTab.getWebView());
5481f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        }
549f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
5501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // If the tab was the current tab, we have to attach
5511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        // it to the view system again.
5521f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        attachTabToContentView(appTab);
5531f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (needsLoad) {
5541f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            urlData.loadIn(appTab.getWebView());
555f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
556f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
557f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
558cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                } else {
559cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // No matching application tab, try to find a regular tab
560cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    // with a matching url.
561cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    appTab = mTabControl.findUnusedTabWithUrl(urlData.mUrl);
56225515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                    if (appTab != null) {
56325515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        if (current != appTab) {
56425515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                            switchToTab(mTabControl.getTabIndex(appTab));
56525515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        }
56625515f8bd458a2471d13d876cfb0e18d8ff2a00fLeon Scroggins                        // Otherwise, we are already viewing the correct tab.
567cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    } else {
568cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url
569cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // will be opened in a new tab unless we have reached
570cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // MAX_TABS. Then the url will be opened in the current
571cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // tab. If a new tab is created, it will have "true" for
572cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                        // exit on close.
5731f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        openTabAndShow(urlData, true, appId);
574cd11589fc3930906d4b9b7dd18aa52a9f1eb0c8aPatrick Scott                    }
575f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
5760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
57725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("about:debug".equals(urlData.mUrl)) {
5780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSettings.toggleDebugSettings();
5790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Get rid of the subwindow if it exists
5821f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                dismissSubWindow(current);
5831f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                urlData.loadIn(current.getWebView());
5840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
5870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
588565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
589565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
590565505b1a2c1d3099496af5910760087602e994aSatish Sampath
591565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
592565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
593565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
594565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
595565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
596565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
597565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
598565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
599565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
600565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
601565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
602565505b1a2c1d3099496af5910760087602e994aSatish Sampath
603565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
604565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
605565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
606565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
607565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
608565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
609565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
610565505b1a2c1d3099496af5910760087602e994aSatish Sampath
611565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
612565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
613565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
614565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getData().toString();
615565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
616565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
617565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
618565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
619565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
6200485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA),
6210485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert                intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
622565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
623565505b1a2c1d3099496af5910760087602e994aSatish Sampath
624565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
625565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
626565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
627565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
628565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
6290485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert    private boolean handleWebSearchRequest(String inUrl, Bundle appData, String extraData) {
630565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
631565505b1a2c1d3099496af5910760087602e994aSatish Sampath
632565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
633565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
634565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
635565505b1a2c1d3099496af5910760087602e994aSatish Sampath
636565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
637565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
638565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Regex.WEB_URL_PATTERN.matcher(url).matches()
639bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
640565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
641565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
642565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
643565505b1a2c1d3099496af5910760087602e994aSatish Sampath
644565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.updateVisitedHistory(mResolver, url, false);
645565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.addSearchUrl(mResolver, url);
646565505b1a2c1d3099496af5910760087602e994aSatish Sampath
647565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
648565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
649565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
65015e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
65115e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
65215e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
6530485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        if (extraData != null) {
6540485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert            intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
6550485170e03e079eb61b9dd52fc2c98da02fa7b2cBjorn Bringert        }
656cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
657565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
658565505b1a2c1d3099496af5910760087602e994aSatish Sampath
659565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
660565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
661565505b1a2c1d3099496af5910760087602e994aSatish Sampath
66225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
6630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
67525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("inline:".equals(url)) {
67625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    return new InlinedUrlData(
67725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_CONTENT),
67825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getType(),
67925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_ENCODING),
68025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_FAILURL));
68125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
6820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
6830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
6840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
6850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
6860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
6870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
6880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Don't add Urls, just search terms.
6890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Urls will get added when the page is loaded.
6900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!Regex.WEB_URL_PATTERN.matcher(url).matches()) {
6910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Browser.updateVisitedHistory(mResolver, url, false);
6920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
6930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
6960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = appData.getString(SearchManager.SOURCE);
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
7050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
7060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
7070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
7080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
71225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        return new UrlData(url);
7130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
716652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // FIXME: Converting the url to lower case
717652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // duplicates functionality in smartUrlFilter().
718652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // However, changing all current callers of fixUrl to
719652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // call smartUrlFilter in addition may have unwanted
720652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        // consequences, and is deferred for now.
721652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        int colon = inUrl.indexOf(':');
722652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        boolean allLower = true;
723652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        for (int index = 0; index < colon; index++) {
724652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            char ch = inUrl.charAt(index);
725652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (!Character.isLetter(ch)) {
726652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                break;
727652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
728652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            allLower &= Character.isLowerCase(ch);
729652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            if (index == colon - 1 && !allLower) {
730652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                inUrl = inUrl.substring(0, colon).toLowerCase()
731652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark                        + inUrl.substring(colon);
732652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark            }
733652ff87f0905abd11f2fdb6cb4de7840985a0810Cary Clark        }
7340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
7350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
7370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
7380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
7390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
7400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
7430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
7460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Looking for the pattern like this
7470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
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    private final SensorListener mSensorListener = new SensorListener() {
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private long mLastGestureTime;
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrev = new float[3];
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrevDiff = new float[3];
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mDiff = new float[3];
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mRevertDiff = new float[3];
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onSensorChanged(int sensor, float[] values) {
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean show = false;
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            float[] diff = new float[3];
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            for (int i = 0; i < 3; i++) {
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                diff[i] = values[i] - mPrev[i];
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Math.abs(diff[i]) > 1) {
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    show = true;
7700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((diff[i] > 1.0 && mDiff[i] < 0.2)
7720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        || (diff[i] < -1.0 && mDiff[i] > -0.2)) {
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // start track when there is a big move, or revert
7740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mRevertDiff[i] = mDiff[i];
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = 0;
7760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else if (diff[i] > -0.2 && diff[i] < 0.2) {
7770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // reset when it is flat
7780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = mRevertDiff[i]  = 0;
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mDiff[i] += diff[i];
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrevDiff[i] = diff[i];
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrev[i] = values[i];
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
7860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only shows if we think the delta is big enough, in an attempt
7870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // to detect "serious" moves left/right or up/down
7880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "sensorChanged " + sensor + " ("
7890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + values[0] + ", " + values[1] + ", " + values[2] + ")"
7900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + " diff(" + diff[0] + " " + diff[1] + " " + diff[2]
7910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + ")");
7920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "      mDiff(" + mDiff[0] + " "
7930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mDiff[1] + " " + mDiff[2] + ")" + " mRevertDiff("
7940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[0] + " " + mRevertDiff[1] + " "
7950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[2] + ")");
7960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            long now = android.os.SystemClock.uptimeMillis();
7990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (now - mLastGestureTime > 1000) {
8000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mLastGestureTime = 0;
8010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float y = mDiff[1];
8030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float z = mDiff[2];
8040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ay = Math.abs(y);
8050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float az = Math.abs(z);
8060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ry = mRevertDiff[1];
8070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float rz = mRevertDiff[2];
8080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ary = Math.abs(ry);
8090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float arz = Math.abs(rz);
8100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestY = ay > 2.5f && ary > 1.0f && ay > ary;
8110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestZ = az > 3.5f && arz > 1.0f && az > arz;
8120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((gestY || gestZ) && !(gestY && gestZ)) {
8140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = mTabControl.getCurrentWebView();
8150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (view != null) {
8170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (gestZ) {
8180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (z < 0) {
8190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomOut();
8200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            } else {
8210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomIn();
8220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
8230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
8240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            view.flingScroll(0, Math.round(y * 100));
8250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
8260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
8270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastGestureTime = now;
8280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
8290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onAccuracyChanged(int sensor, int accuracy) {
8330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TODO Auto-generated method stub
8340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
8370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onResume() {
8390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
84031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
8410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
8420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
8450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
8460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
8470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8497bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
8500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
8517bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
8520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
8540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
8550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
8560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null) {
8590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
8600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // In case credential request never comes back
8610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
8620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
8660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
8670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
8680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.doFlick()) {
8700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSensorManager == null) {
8710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSensorManager = (SensorManager) getSystemService(
8720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Context.SENSOR_SERVICE);
8730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.registerListener(mSensorListener,
8750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_ACCELEROMETER,
8760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_DELAY_FASTEST);
8770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
8780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager = null;
8790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
8810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8823bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
8833bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Since the actual title bar is embedded in the WebView, and removing it
8843bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * would change its appearance, create a temporary title bar to go at
8853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * the top of the screen while the menu is open.
8863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
8873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private TitleBar mFakeTitleBar;
8883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
8893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
890d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Holder for the fake title bar.  It will have a foreground shadow, as well
891d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * as a white background, so the fake title bar looks like the real one.
892d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
893d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private ViewGroup mFakeTitleBarHolder;
894d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins
895d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
896d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     * Layout parameters for the fake title bar within mFakeTitleBarHolder
897d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins     */
898d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    private FrameLayout.LayoutParams mFakeTitleBarParams
899d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            = new FrameLayout.LayoutParams(
900c01e4a8342c9478f9ba0c53c2ebca25b4b5c3173Leon Scroggins            ViewGroup.LayoutParams.FILL_PARENT,
901d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            ViewGroup.LayoutParams.WRAP_CONTENT);
902d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins    /**
9033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Keeps track of whether the options menu is open.  This is important in
9043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * determining whether to show or hide the title bar overlay.
9053bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
9063bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mOptionsMenuOpen;
9073bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9083bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
9093bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful when mOptionsMenuOpen is true.  This variable keeps track
9103bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * of whether the configuration has changed.  The first onMenuOpened call
9113bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * after a configuration change is simply a reopening of the same menu
9123bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * (i.e. mIconView did not change).
9133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
9143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mConfigChanged;
9153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
9173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Whether or not the options menu is in its smaller, icon menu form.  When
9183bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * true, we want the title bar overlay to be up.  When false, we do not.
9193bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Only meaningful if mOptionsMenuOpen is true.
9203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
9213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private boolean mIconView;
9223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
923a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    @Override
924a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    public boolean onMenuOpened(int featureId, Menu menu) {
9253bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (Window.FEATURE_OPTIONS_PANEL == featureId) {
9263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mOptionsMenuOpen) {
9273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                if (mConfigChanged) {
9283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // We do not need to make any changes to the state of the
9293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // title bar, since the only thing that happened was a
9303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    // change in orientation
9313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    mConfigChanged = false;
9323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                } else {
9333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    if (mIconView) {
9343bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu to expanded view, so hide the
9353bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar.
9363bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        hideFakeTitleBar();
9373bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = false;
9383bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    } else {
9393bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // Switching the menu back to icon view, so show the
9403bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        // title bar once again.
9413bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        showFakeTitleBar();
9423bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                        mIconView = true;
9433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    }
9443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                }
9453bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            } else {
9463bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                // The options menu is closed, so open it, and show the title
9473bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                showFakeTitleBar();
9483bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mOptionsMenuOpen = true;
9493bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mConfigChanged = false;
9503bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mIconView = true;
9513bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            }
9523bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
953a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins        return true;
954a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins    }
955a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
9563bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void showFakeTitleBar() {
957f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott        final View decor = getWindow().peekDecorView();
9584d7e406998028f9ddb01df6d7463b87d6fa02601Leon Scroggins        if (mFakeTitleBar == null && mActiveTabsPage == null
959f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && !mActivityInPause && decor != null
960f8de8ecc321fe5b45846adc38d174d5bc2208f20Patrick Scott                && decor.getWindowToken() != null) {
961f4bb18a41259ce62209c768484547d33583f9c77Leon Scroggins            final WebView webView = getTopWindow();
96268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            mFakeTitleBar = new TitleBar(this);
9633bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setTitleAndUrl(null, webView.getUrl());
9643bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setProgress(webView.getProgress());
9653bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setFavicon(webView.getFavicon());
9663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            updateLockIconToLatest();
9673bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9683bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager manager
9693bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
9703bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
9713bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // Add the title bar to the window manager so it can receive touches
9723bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // while the menu is up
9733bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            WindowManager.LayoutParams params
9743bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = new WindowManager.LayoutParams(
9753bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.FILL_PARENT,
9763bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    ViewGroup.LayoutParams.WRAP_CONTENT,
9773bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
9783bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
979685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    PixelFormat.TRANSLUCENT);
9803bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.gravity = Gravity.TOP;
981a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            WebView mainView = mTabControl.getCurrentWebView();
982685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            boolean atTop = mainView != null && mainView.getScrollY() == 0;
983685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            params.windowAnimations = atTop ? 0
984685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins                    : com.android.internal.R.style.Animation_DropDownDown;
9853bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // XXX : Without providing an offset, the fake title bar will be
9863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // placed underneath the status bar.  Use the global visible rect
9873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            // of mBrowserFrameLayout to determine the bottom of the status bar
9883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            Rect rectangle = new Rect();
9893bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mBrowserFrameLayout.getGlobalVisibleRect(rectangle);
9903bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            params.y = rectangle.top;
991685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // Add a holder for the title bar.  It also holds a shadow to show
992685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            // below the title bar.
993d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            if (mFakeTitleBarHolder == null) {
994d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                mFakeTitleBarHolder = (ViewGroup) LayoutInflater.from(this)
995d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins                    .inflate(R.layout.title_bar_bg, null);
996d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            }
997685498685d8424f48d77d26d8d5790da34645f44Leon Scroggins            mFakeTitleBarHolder.addView(mFakeTitleBar, 0, mFakeTitleBarParams);
998d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins            manager.addView(mFakeTitleBarHolder, params);
9993bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        }
10003bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
10013bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
10023bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    @Override
10033bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    public void onOptionsMenuClosed(Menu menu) {
10043bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mOptionsMenuOpen = false;
1005a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        if (!mInLoad) {
1006a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            hideFakeTitleBar();
1007a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        } else if (!mIconView) {
1008a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // The page is currently loading, and we are in expanded mode, so
1009a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // we were not showing the menu.  Show it once again.  It will be
1010a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            // removed when the page finishes.
1011a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            showFakeTitleBar();
1012a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins        }
10133bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
10143bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    private void hideFakeTitleBar() {
10153bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (mFakeTitleBar == null) return;
10163bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        WindowManager manager
10173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                    = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
1018d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        mFakeTitleBarHolder.removeView(mFakeTitleBar);
1019d8fd2fcf4eb037fd65ae923c6dbeff6c6ecb4d4fLeon Scroggins        manager.removeView(mFakeTitleBarHolder);
10203bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mFakeTitleBar = null;
10213bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
10223bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
10230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onSaveInstanceState(Bundle outState) {
102931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onPause() {
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10507bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
10527bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the credentials toast if it is up
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null && mCredsDlg.isShowing()) {
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1064a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // FIXME: This removes the active tabs page and resets the menu to
1065a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // MAIN_MENU.  A better solution might be to do this work in onNewIntent
1066a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // but then we would need to save it in onSaveInstanceState and restore
1067a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        // it in onCreate/onRestoreInstanceState
1068a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        if (mActiveTabsPage != null) {
1069a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins            removeActiveTabPage(true);
1070a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins        }
1071a2ab6a7dc0f7023c1d7ebb1cbad397c5dc3d6453Leon Scroggins
10720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
10770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSensorManager != null) {
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.unregisterListener(mSensorListener);
10800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onDestroy() {
108431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
10850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
10890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab t = mTabControl.getCurrentTab();
1090fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1091fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1092fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1093fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mGlsConnection != null) {
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            unbindService(mGlsConnection);
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mGlsConnection = null;
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // stop MASF proxy service
11040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //   (new ComponentName(
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //stopService(proxyServiceIntent);
1111b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
1112b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
11173bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        mConfigChanged = true;
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoFromShowSSLCertificateOnError.booleanValue());
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mFindDialog != null && mFindDialog.isShowing()) {
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mFindDialog.onConfigurationChanged(newConfig);
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public void onLowMemory() {
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11627bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean resumeWebViewTimers() {
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if ((!mActivityInPause && !mPageStarted) ||
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (mActivityInPause && mPageStarted)) {
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
11670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11767bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause && !mPageStarted) {
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
11860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11891f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // FIXME: Do we want to call this when loading google for the first time?
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called when we are launching for the first time. We
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * are waiting for the login credentials before loading Google home
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * pages. This way the user will be logged in straight away.
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void waitForCredentials() {
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show a toast
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = new ProgressDialog(this);
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setIndeterminate(true);
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the user cancels the operation, then cancel the Google
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Credentials request.
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.show();
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // We set a timeout for the retrieval of credentials in onResume()
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // as that is when we have freed up some CPU time to get
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the login credentials.
12080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If we have received the credentials or we have timed out and we are
12120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * showing the credentials dialog, then it is time to move on.
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resumeAfterCredentials() {
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg == null) {
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the toast
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg.isShowing()) {
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear any pending timeout
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
12270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the page
12290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
12300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
12310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.loadUrl(mSettings.getHomePage());
12320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Update the settings, need to do this last as it can take a moment
12350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to persist the settings. In the mean time we could be loading
12360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // content.
12370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setLoginInitialized(this);
12380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
12450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Cursor c = Browser.getAllBookmarks(mResolver);
12460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!c.moveToFirst()) {
12470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.deactivate();
12480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
12490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
12510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            do {
12520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = c.getString(urlIndex);
12530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                db.retainIconForPageUrl(url);
12540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } while (c.moveToNext());
12550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            c.deactivate();
12560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
12570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
12580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
12620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
12630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
12640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
12680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
12690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
12710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
12720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
12730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
12740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
12750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
12780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
12790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
12800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
12810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
12830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
12840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
12870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
12880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
12890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
12900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
12910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
12920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
12960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
12970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
12980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
12990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
13000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView webView = getTopWindow();
13010d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        if (null == webView) {
13020d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
13030d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
13040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final HashMap hrefMap = new HashMap();
13050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        hrefMap.put("webview", webView);
13060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Message msg = mHandler.obtainMessage(
13070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                FOCUS_NODE_HREF, id, 0, hrefMap);
13080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
13090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
13120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
13130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
13140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
13150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
13160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
13170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
13180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
13200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
13210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return onOptionsItemSelected(item);
13220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
13240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
13250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
13280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
13290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bundle.putString(SearchManager.SOURCE, source);
13300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
13310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
13344e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project     * Overriding this to insert a local information bundle
13350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
13360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onSearchRequested() {
133868579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        if (mOptionsMenuOpen) closeOptionsMenu();
13395bbe98025a2c606a35c91b826760020890daadb1Leon Scroggins        String url = (getTopWindow() == null) ? null : getTopWindow().getUrl();
134083f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
13414e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
13420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
13430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
13470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
13480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
13490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
13500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
13520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13541f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
13551f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * Switch tabs.  Called by the TitleBarSet when sliding the title bar
13561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     * results in changing tabs.
1357160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param index Index of the tab to change to, as defined by
1358160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *              mTabControl.getTabIndex(Tab t).
1359160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @return boolean True if we successfully switched to a different tab.  If
1360160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the indexth tab is null, or if that tab is the same as
1361160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                 the current one, return false.
13621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
1363160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /* package */ boolean switchToTab(int index) {
13641f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        TabControl.Tab tab = mTabControl.getTab(index);
13651f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        TabControl.Tab currentTab = mTabControl.getCurrentTab();
13661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (tab == null || tab == currentTab) {
1367160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return false;
13681f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13691f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (currentTab != null) {
13701f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // currentTab may be null if it was just removed.  In that case,
13711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // we do not need to remove it
13721f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            removeTabFromContentView(currentTab);
13731f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
13741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.setCurrentTab(tab);
13751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        attachTabToContentView(tab);
1376eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        resetTitleIconAndProgress();
1377eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        updateLockIconToLatest();
1378160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        return true;
13791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
13801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
13810a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ TabControl.Tab openTabToHomePage() {
13820a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        return openTabAndShow(mSettings.getHomePage(), false, null);
13830a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
13840a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
13851f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ void closeCurrentWindow() {
13861f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        final TabControl.Tab current = mTabControl.getCurrentTab();
1387160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (mTabControl.getTabCount() == 1) {
1388304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // This is the last tab.  Open a new one, with the home
1389304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins            // page and close the current one.
13900a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            TabControl.Tab newTab = openTabToHomePage();
1391160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1392160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            return;
1393160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
13941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        final TabControl.Tab parent = current.getParentTab();
13951f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        int indexToShow = -1;
13961f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (parent != null) {
13971f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            indexToShow = mTabControl.getTabIndex(parent);
13981f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        } else {
1399160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            final int currentIndex = mTabControl.getCurrentIndex();
1400160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Try to move to the tab to the right
1401160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            indexToShow = currentIndex + 1;
1402160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (indexToShow > mTabControl.getTabCount() - 1) {
1403160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                // Try to move to the tab to the left
1404160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins                indexToShow = currentIndex - 1;
14051f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            }
14061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        }
1407160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        if (switchToTab(indexToShow)) {
1408160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            // Close window
1409160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            closeTab(current);
1410160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins        }
14111f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    }
14121f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins
14130a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    private ActiveTabsPage mActiveTabsPage;
14140a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14150a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /**
14160a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Remove the active tabs page.
14170a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * @param needToAttach If true, the active tabs page did not attach a tab
14180a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     *                     to the content view, so we need to do that here.
14190a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     */
14200a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void removeActiveTabPage(boolean needToAttach) {
14210a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mContentView.removeView(mActiveTabsPage);
14220a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mActiveTabsPage = null;
14230a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mMenuState = R.id.MAIN_MENU;
14240a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (needToAttach) {
14250a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            attachTabToContentView(mTabControl.getCurrentTab());
14260a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
14270a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        getTopWindow().requestFocus();
14280a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    }
14290a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
14320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
14330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
14340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
14350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
14360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14371f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        if (null == getTopWindow()) {
14380d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
14390d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
14406ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
14416ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
14426ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
14436ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
14446ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
14456ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
14466ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
14470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
1449a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins            case R.id.new_tab_menu_id:
14500a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                openTabToHomePage();
1451a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                break;
1452a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
145364b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins            case R.id.goto_menu_id:
1454304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(false);
14550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14570a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            case R.id.active_tabs_menu_id:
14580a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage = new ActiveTabsPage(this, mTabControl);
14590a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(mTabControl.getCurrentTab());
146043de61666cfc98a3acc41c7161a1a8b0bdb2b72bLeon Scroggins                hideFakeTitleBar();
14610a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mContentView.addView(mActiveTabsPage, COVER_SCREEN_PARAMS);
14620a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mActiveTabsPage.requestFocus();
14630a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                mMenuState = EMPTY_MENU;
14640a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                break;
14650a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins
14661f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            case R.id.add_bookmark_menu_id:
14671f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                Intent i = new Intent(BrowserActivity.this,
14681f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        AddBookmarkPage.class);
14691f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView w = getTopWindow();
14701f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("url", w.getUrl());
14711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                i.putExtra("title", w.getTitle());
147283cdb2c40f2dbcbdf522a2af0ec8224c7195c6c1Grace Kloba                i.putExtra("touch_icon_url", w.getTouchIconUrl());
1473dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                i.putExtra("thumbnail", createScreenshot(w));
14741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                startActivity(i);
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
14800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
14960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14991f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeCurrentWindow();
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TabControl.Tab current = mTabControl.getCurrentTab();
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current.getWebView().loadUrl(mSettings.getHomePage());
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.setWebView(getTopWindow());
15210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.show();
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
15300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
1533304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                bookmarksOrHistoryPicker(true);
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Browser.sendString(this, getTopWindow().getUrl());
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
15410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
15420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
15650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
15660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
15670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            TabControl.Tab desiredTab = mTabControl.getTab(id);
15690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
15711f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                                switchToTab(id);
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onPrepareOptionsMenu(Menu menu)
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    {
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1634a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                menu.findItem(R.id.new_tab_menu_id).setEnabled(
1635a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins                        mTabControl.getTabCount() < TabControl.MAX_TABS);
1636a81a764063d2f849fba0cbc3039f86e67c2960ddLeon Scroggins
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
17045e335a381a0cd66e94117b202c1f34f5cb29c9b8Cary Clark                addIntent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
17240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
17280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
17310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
17360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
17370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
17380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getTabCount() < TabControl.MAX_TABS);
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
17510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
1766c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba    // this should only be called for the current tab.
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachTabToContentView(TabControl.Tab t) {
17682bc69918d97a767a02132090e58718077381ba1aSteve Block        // Attach the container that contains the main WebView and any other UI
17692bc69918d97a767a02132090e58718077381ba1aSteve Block        // associated with the tab.
1770d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachTabToContentView(mContentView);
1771bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1772bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mShouldShowErrorConsole) {
1773bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(true);
1774bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() == 0) {
1775bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
1776bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
1777bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
1778bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
1779bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1780bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
1781bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
1782bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
1783bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1784bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1785c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        setLockIconType(t.getLockIconType());
1786c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        setPrevLockType(t.getPrevLockIconType());
1787c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba
1788c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        // this is to match the code in removeTabFromContentView()
1789c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        if (!mPageStarted && t.getTopWindow().getProgress() < 100) {
1790c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            mPageStarted = true;
1791eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        }
1792eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba
179339ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
179455a5bc2a8f3c9a0721eeaa5a45241e00d5da95efLeon Scroggins        view.setEmbeddedTitleBar(mTitleBar);
17950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
17960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
17970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
18000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachSubWindow(TabControl.Tab t) {
1801d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.attachSubWindow(mContentView);
1802d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
18060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void removeTabFromContentView(TabControl.Tab t) {
18072bc69918d97a767a02132090e58718077381ba1aSteve Block        // Remove the container that contains the main WebView.
1808d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeTabFromContentView(mContentView);
1809bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
1810bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (mTabControl.getCurrentErrorConsole(false) != null) {
1811bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(mTabControl.getCurrentErrorConsole(false));
1812bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
1813bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
181439ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins        WebView view = t.getWebView();
1815bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        if (view != null) {
1816bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins            view.setEmbeddedTitleBar(null);
1817bb85b9016201d45ea939d7cb7edd0ba6616a111cLeon Scroggins        }
181839ab28eba0c8c837ac80851ec0dd2af336aa3f85Leon Scroggins
1819c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        // unlike attachTabToContentView(), removeTabFromContentView() can be
1820c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba        // called for the non-current tab. Need to add the check.
1821eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        if (t == mTabControl.getCurrentTab()) {
1822eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            t.setLockIconType(getLockIconType());
1823eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            t.setPrevLockIconType(getPrevLockType());
1824c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba
1825c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // this is not a perfect solution. But currently there is one
1826c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // WebViewClient for all the WebView. if user switches from an
1827c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // in-load window to an already loaded window, mPageStarted will not
1828c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // be set to false. If user leaves the Browser, pauseWebViewTimers()
1829c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // won't do anything and leaves the timer running even Browser is in
1830c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            // the background.
1831c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            if (mPageStarted) {
1832c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba                mPageStarted = false;
1833c928c30a51eee84b40cb7045842c288c1cfafff0Grace Kloba            }
1834eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        }
18350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
18380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void dismissSubWindow(TabControl.Tab t) {
1840d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        t.removeSubWindow(mContentView);
1841d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        // Tell the TabControl to dismiss the subwindow. This will destroy
1842d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        // the WebView.
1843d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        mTabControl.dismissSubWindow(t);
1844d0119535d0c490e087be114ae8fd1639bb1945dcPatrick Scott        getTopWindow().requestFocus();
18450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18471f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // A wrapper function of {@link #openTabAndShow(UrlData, boolean, String)}
184825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
18491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    private TabControl.Tab openTabAndShow(String url, boolean closeOnExit,
18501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            String appId) {
18511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        return openTabAndShow(new UrlData(url), closeOnExit, appId);
18520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
18550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
18561f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    // url isn't null, it will load the given url.
18571f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ TabControl.Tab openTabAndShow(UrlData urlData,
1858f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            boolean closeOnExit, String appId) {
18590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final boolean newTab = mTabControl.getTabCount() != TabControl.MAX_TABS;
18600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab currentTab = mTabControl.getCurrentTab();
18610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (newTab) {
18621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            final TabControl.Tab tab = mTabControl.createNewTab(
18631f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                    closeOnExit, appId, urlData.mUrl);
18641f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            WebView webview = tab.getWebView();
18650a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // If the last tab was removed from the active tabs page, currentTab
18660a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            // will be null.
18670a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            if (currentTab != null) {
18680a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins                removeTabFromContentView(currentTab);
18690a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            }
18708bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // We must set the new tab as the current tab to reflect the old
18718bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            // animation behavior.
18728bbd69f50abd537bfe7eb314b3a3e20241ac22bdPatrick Scott            mTabControl.setCurrentTab(tab);
1873eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba            attachTabToContentView(tab);
1874160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins            if (!urlData.isEmpty()) {
18751f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                urlData.loadIn(webview);
18760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18771f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return tab;
187864b80f3efd95d7b5192731e995ccde79c4c6c11fLeon Scroggins        } else {
18791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            // Get rid of the subwindow if it exists
18801f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            dismissSubWindow(currentTab);
18811f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            if (!urlData.isEmpty()) {
18821f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Load the given url.
18831f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                urlData.loadIn(currentTab.getWebView());
18840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
18850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
1886c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba        return currentTab;
18870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1889c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba    private TabControl.Tab openTab(String url) {
18900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
1891f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            TabControl.Tab t = mTabControl.createNewTab();
18920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
18931f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                WebView view = t.getWebView();
18941f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                view.loadUrl(url);
18950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
1896c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
18970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
18981f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            return openTabAndShow(url, false, null);
18990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
19070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
19110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
19160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
19170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
19190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
19200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
19210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
19240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
19250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
19290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
19300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
19310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
19320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
19330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
19340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
19350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
19410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
19420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
19430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        revertLockIcon();
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
19540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
19550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
19560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
19570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
19580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
19590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
19610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
19620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebChromeClient.onProgressChanged(current, progress);
19630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
19660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
196968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(item.getUrl(), item.getTitle());
19700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
19710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
197268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(null, null);
19730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
19790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
19800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
198268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private void setUrlTitle(String url, String title) {
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
19850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
198668579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setTitleAndUrl(title, url);
19873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (mFakeTitleBar != null) {
19883bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setTitleAndUrl(title, url);
19890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
19930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
19940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
19950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
200032e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
20060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setFavicon(Bitmap icon) {
203168579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setFavicon(icon);
20323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (mFakeTitleBar != null) {
20333bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setFavicon(icon);
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Saves the current lock-icon state before resetting
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the lock icon. If we have an error, we may need to
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * roll back to the previous state.
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void saveLockIcon() {
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPrevLockType = mLockIconType;
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
20470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reverts the lock-icon state to the last saved state,
20480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * for example, if we had an error, and need to cancel
20490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the load.
20500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void revertLockIcon() {
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = mPrevLockType;
20530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
205431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
20550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.revertLockIcon:" +
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  " revert lock icon to " + mLockIconType);
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20593bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        updateLockIconToLatest();
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20621f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /**
20630a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * Close the tab, remove its associated title bar, and adjust mTabControl's
20640a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins     * current tab to a valid value.
20651f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins     */
20660a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins    /* package */ void closeTab(TabControl.Tab t) {
20670a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int currentIndex = mTabControl.getCurrentIndex();
20680a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        int removeIndex = mTabControl.getTabIndex(t);
20691f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins        mTabControl.removeTab(t);
20700a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        if (currentIndex >= removeIndex && currentIndex != 0) {
20710a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins            currentIndex--;
20720a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        }
20730a64ba581c9e476ef10f36a62825df933771427dLeon Scroggins        mTabControl.setCurrentTab(mTabControl.getTab(currentIndex));
2074a5bf1deca120315a2643ea5b010f94d853461b15Andrei Popescu        resetTitleIconAndProgress();
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void goBackOnePageOrQuit() {
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
20850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            TabControl.Tab parent = current.getParentTab();
20960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
20971f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
20981f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we close the other tab
20991f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
21000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
2102bb0af5ced906e5100d54f0c08e073e669edf2290Grace Kloba                    // force mPageStarted to be false as we are going to either
2103bb0af5ced906e5100d54f0c08e073e669edf2290Grace Kloba                    // finish the activity or remove the tab. This will ensure
2104bb0af5ced906e5100d54f0c08e073e669edf2290Grace Kloba                    // pauseWebView() taking action.
2105bb0af5ced906e5100d54f0c08e073e669edf2290Grace Kloba                    mPageStarted = false;
21060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
21070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
21080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
21090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21107bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
21117bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
2112ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // Temporarily change mActivityInPause to be true as
2113ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // pauseWebViewTimers() will do nothing if mActivityInPause
2114ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                    // is false.
2115918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    boolean savedState = mActivityInPause;
2116918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    if (savedState) {
2117ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                        Log.e(LOGTAG, "BrowserActivity is already paused "
2118ec1b5ad8d8283b1fbbc5d7fa1cd50ef95b9e594dGrace Kloba                                + "while handing goBackOnePageOrQuit.");
2119918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    }
2120918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = true;
21217bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
2122918e1d78b2db6ef21c71a07868572d9cda498476Grace Kloba                    mActivityInPause = savedState;
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
21270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
21300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
21330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
21340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21385942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21395942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyDown(int keyCode, KeyEvent event) {
21405942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
21415942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // still down, we don't want to trigger the search. Pretend to consume
21425942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        // the key and do nothing.
21435942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        if (mMenuIsDown) return true;
21445942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba
21455942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21465942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
21475942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = true;
21485942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21495942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
21505942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                // Browser's hidden shortcut key. Don't call super so that
21515942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                // search won't be triggered.
21525942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
21535942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21545942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.getRepeatCount() == 0) {
21555942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    event.startTracking();
21565942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21575942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else if (mCustomView == null && mActiveTabsPage == null
21585942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        && event.isLongPress()) {
21595942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    bookmarksOrHistoryPicker(true);
21605942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
21610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21625942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21645942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyDown(keyCode, event);
21650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21675942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    @Override
21685942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba    public boolean onKeyUp(int keyCode, KeyEvent event) {
21695942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        switch(keyCode) {
21705942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_MENU:
21715942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                mMenuIsDown = false;
21725942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
21735942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_SPACE:
21745942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isShiftPressed()) {
21755942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    getTopWindow().pageUp(false);
21765942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                } else {
21775942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    getTopWindow().pageDown(false);
21785942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
21795942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                return true;
21805942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba            case KeyEvent.KEYCODE_BACK:
21815942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                if (event.isTracking() && !event.isCanceled()) {
21825942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    if (mCustomView != null) {
21835942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if a custom view is showing, hide it
21845942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        mWebChromeClient.onHideCustomView();
21855942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    } else if (mActiveTabsPage != null) {
21865942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        // if tab page is showing, hide it
21875942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        removeActiveTabPage(true);
21880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
21895942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        WebView subwindow = mTabControl.getCurrentSubWindow();
21905942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        if (subwindow != null) {
21915942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            if (subwindow.canGoBack()) {
21925942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                subwindow.goBack();
21935942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            } else {
21945942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                                dismissSubWindow(mTabControl.getCurrentTab());
21955942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            }
21965942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        } else {
21975942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                            goBackOnePageOrQuit();
21985942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                        }
21990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22005942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                    return true;
22015942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                }
22025942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba                break;
22030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22045942df0c38dff7e4335e352e2d03f100b07b8907Grace Kloba        return super.onKeyUp(keyCode, event);
22050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
220768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    /* package */ void stopLoading() {
22080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
22100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
22110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebViewClient.onPageFinished(w, w.getUrl());
22120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
22140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
22150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
22160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
22200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
22210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
22220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
22230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // called by a non-UI thread to post the message
22270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void postMessage(int what, int arg1, int arg2, Object obj) {
22280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2, obj));
22290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
22320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
22330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
22340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
22360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
22370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CANCEL_CREDS_REQUEST    = 103;
223892c18a52ca7a79c114028b5ba22c3dfe443bd1a4Grace Kloba    private static final int RELEASE_WAKELOCK        = 107;
22390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
22410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
22420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
22440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
22460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
22480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
22520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
22540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
22550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            loadURL(getTopWindow(), url);
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
2262c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            final TabControl.Tab parent = mTabControl
2263c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                    .getCurrentTab();
2264c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            final TabControl.Tab newTab = openTab(url);
2265c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2266c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2267c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
22710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
22720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
22730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
22740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Browser.sendString(BrowserActivity.this, url);
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
22800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
22820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
22840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
22850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    loadURL(getTopWindow(), (String) msg.obj);
22900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
22910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
22930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
22940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
22950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CANCEL_CREDS_REQUEST:
22970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    resumeAfterCredentials();
22980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
22990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
23010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
23020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
23030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
23060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
230989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    private void updateScreenshot(WebView view) {
231089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // If this is a bookmarked site, add a screenshot to the database.
231189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: When should we update?  Every time?
231289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // FIXME: Would like to make sure there is actually something to
231389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // draw, but the API for that (WebViewCore.pictureReady()) is not
231489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        // currently accessible here.
23153918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        ContentResolver cr = getContentResolver();
23163918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        final Cursor c = BrowserBookmarksAdapter.queryBookmarksForUrl(
2317a5d669e4c08f0e64387c2c539c41a26ac8c845abLeon Scroggins                cr, view.getOriginalUrl(), view.getUrl(), false);
23183918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        if (c != null) {
231989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            boolean succeed = c.moveToFirst();
232089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            ContentValues values = null;
232189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            while (succeed) {
232289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                if (values == null) {
232389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    final ByteArrayOutputStream os
232489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            = new ByteArrayOutputStream();
2325dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                    Bitmap bm = createScreenshot(view);
232689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    bm.compress(Bitmap.CompressFormat.PNG, 100, os);
232789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values = new ContentValues();
232889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                    values.put(Browser.BookmarkColumns.THUMBNAIL,
232989c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                            os.toByteArray());
233089c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                }
233189c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                cr.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
233289c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                        c.getInt(0)), values, null, null);
233389c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins                succeed = c.moveToNext();
233489c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            }
233589c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            c.close();
233689c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins        }
233789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins    }
233889c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins
2339dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    private Bitmap createScreenshot(WebView view) {
2340dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Picture thumbnail = view.capturePicture();
2341dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // Keep width and height in sync with BrowserBookmarksPage
2342dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // and bookmark_thumb
2343dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap bm = Bitmap.createBitmap(100, 80,
2344dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch                Bitmap.Config.ARGB_4444);
2345dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Canvas canvas = new Canvas(bm);
2346dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // May need to tweak these values to determine what is the
2347dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        // best scale factor
2348dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        canvas.scale(.5f, .5f);
2349dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        thumbnail.draw(canvas);
2350dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        return bm;
2351dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch    }
2352dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
23530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
23540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebViewClient implementation.
23550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
23560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
23580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
23590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
23600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
23610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
23620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebViewClient getWebViewClient() {
23640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebViewClient;
23650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23673918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott    private void updateIcon(WebView view, Bitmap icon) {
23680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (icon != null) {
23690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
237015525d48024d325c8a52766d8ca727191251a8d4Patrick Scott                    view.getOriginalUrl(), view.getUrl(), icon);
237115525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        }
237215525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        setFavicon(icon);
237315525d48024d325c8a52766d8ca727191251a8d4Patrick Scott    }
237415525d48024d325c8a52766d8ca727191251a8d4Patrick Scott
237515525d48024d325c8a52766d8ca727191251a8d4Patrick Scott    private void updateIcon(String url, Bitmap icon) {
237615525d48024d325c8a52766d8ca727191251a8d4Patrick Scott        if (icon != null) {
237715525d48024d325c8a52766d8ca727191251a8d4Patrick Scott            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
237815525d48024d325c8a52766d8ca727191251a8d4Patrick Scott                    null, url, icon);
23790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setFavicon(icon);
23810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebViewClient mWebViewClient = new WebViewClient() {
23840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
23850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageStarted(WebView view, String url, Bitmap favicon) {
23860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetLockIcon(url);
238768579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(url, null);
2388bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
238959ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            // If we start a touch icon load and then load a new page, we don't
239059ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            // want to cancel the current touch icon loader. But, we do want to
239159ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            // create a new one when the touch icon url is known.
239259ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            if (mTouchIconLoader != null) {
239359ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                mTouchIconLoader.mActivity = null;
239459ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                mTouchIconLoader = null;
239559ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott            }
239659ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott
2397bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(false);
2398bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole != null) {
2399bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.clearErrorMessages();
2400bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                if (mShouldShowErrorConsole) {
2401bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                    errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
2402bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                }
2403bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
2404bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
24050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Call updateIcon instead of setFavicon so the bookmark
24060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // database can be updated.
240715525d48024d325c8a52766d8ca727191251a8d4Patrick Scott            updateIcon(url, favicon);
24080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24094d7880fe3061ed691d220e64cd9e54a8c7b2d1bfGrace Kloba            if (mSettings.isTracing()) {
24100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String host;
24110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
24120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebAddress uri = new WebAddress(url);
24130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    host = uri.mHost;
24140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (android.net.ParseException ex) {
24154d7880fe3061ed691d220e64cd9e54a8c7b2d1bfGrace Kloba                    host = "browser";
24160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
24170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                host = host.replace('.', '_');
24184d7880fe3061ed691d220e64cd9e54a8c7b2d1bfGrace Kloba                host += ".trace";
24190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = true;
24204d7880fe3061ed691d220e64cd9e54a8c7b2d1bfGrace Kloba                Debug.startMethodTracing(host, 20 * 1024 * 1024);
24210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
24240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
24250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mStart = SystemClock.uptimeMillis();
24260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mProcessStart = Process.getElapsedCpuTime();
24270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
24280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
24290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
24300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mUserStart = sysCpu[0] + sysCpu[1];
24310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSystemStart = sysCpu[2];
24320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIdleStart = sysCpu[3];
24330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
24340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
24350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mUiStart = SystemClock.currentThreadTimeMillis();
24360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mPageStarted) {
24390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = true;
24407bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // if onResume() has been called, resumeWebViewTimers() does
24417bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // nothing.
24427bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                resumeWebViewTimers();
24430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // reset sync timer to avoid sync starts during loading a page
24460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().resetSync();
24470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mInLoad = true;
2449184f5e351dd511e6dc41ba8468565c14d6beb4f5Leon Scroggins            showFakeTitleBar();
24500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateInLoadMenuItems();
24510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mIsNetworkUp) {
2452eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
24530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (view != null) {
24540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    view.setNetworkAvailable(false);
24550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
24560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
24600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageFinished(WebView view, String url) {
24610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Reset the title and icon in case we stopped a provisional
24620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // load.
24630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(view);
24640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Update the lock icon image only once we are done loading
24663bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            updateLockIconToLatest();
246789c6d36e2e6d6040540ee93ef4df29a6874a6a95Leon Scroggins            updateScreenshot(view);
2468b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins
24690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
2470cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project            if (false) {
24710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
24720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
24730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
24740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String uiInfo = "UI thread used "
24750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.currentThreadTimeMillis() - mUiStart)
24760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms";
247731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
24780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, uiInfo);
24790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
24800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //The string that gets written to the log
24810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String performanceString = "It took total "
24820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.uptimeMillis() - mStart)
24830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms clock time to load the page."
24840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + "\nbrowser process used "
24850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (Process.getElapsedCpuTime() - mProcessStart)
24860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, user processes used "
24870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
24880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, kernel used "
24890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[2] - mSystemStart) * 10
24900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
24910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms and irq took "
24920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
24930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            * 10 + " ms, " + uiInfo;
249431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
24950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
24960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
24970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url != null) {
24980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // strip the url to maintain consistency
24990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String newUrl = new String(url);
25000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (newUrl.startsWith("http://www.")) {
25010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(11);
25020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("http://")) {
25030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(7);
25040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://www.")) {
25050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(12);
25060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://")) {
25070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(8);
25080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
250931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGD_ENABLED) {
25100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.d(LOGTAG, newUrl + " loaded");
25110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
25120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        /*
25130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (sWhiteList.contains(newUrl)) {
25140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // The string that gets pushed to the statistcs
25150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // service
25160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            performanceString = performanceString
25170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nWebpage: "
25180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + newUrl
25190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nCarrier: "
25200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + android.os.SystemProperties
25210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            .get("gsm.sim.operator.alpha");
25220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (mWebView != null
25230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext() != null
25240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext().getSystemService(
25250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Context.CONNECTIVITY_SERVICE) != null) {
25260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                ConnectivityManager cManager =
25270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (ConnectivityManager) mWebView
25280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getContext().getSystemService(
25290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        Context.CONNECTIVITY_SERVICE);
25300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                NetworkInfo nInfo = cManager
25310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getActiveNetworkInfo();
25320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (nInfo != null) {
25330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString = performanceString
25340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + "\nNetwork Type: "
25350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + nInfo.getType().toString();
25360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
25370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
25380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Checkin.logEvent(mResolver,
25390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Checkin.Events.Tag.WEBPAGE_LOAD,
25400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString);
25410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.w(LOGTAG, "pushed to the statistics service");
25420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
25430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        */
25440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             }
25470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mInTrace) {
25490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = false;
25500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Debug.stopMethodTracing();
25510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mPageStarted) {
25540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = false;
25557bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // pauseWebViewTimers() will do nothing and return false if
25567bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // onPause() is not called yet.
25577bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                if (pauseWebViewTimers()) {
25580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
25590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.removeMessages(RELEASE_WAKELOCK);
25600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
25610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // return true if want to hijack the url to let another app to handle it
25670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
25680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideUrlLoading(WebView view, String url) {
25690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith(SCHEME_WTAI)) {
25700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/mc;number
25710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
25720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_MC)) {
25730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent intent = new Intent(Intent.ACTION_VIEW,
25740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Uri.parse(WebView.SCHEME_TEL +
25750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            url.substring(SCHEME_WTAI_MC.length())));
25760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    startActivity(intent);
25770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
25780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/sd;dtmf
25800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // dtmf=string(dialstring)
25810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_SD)) {
25820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
25830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // only send when there is active voice connection
25840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
25850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/ap;number;name
25870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
25880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // name=string
25890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_AP)) {
25900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
25910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
25920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25959918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // The "about:" schemes are internal to the browser; don't
25969918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // want these to be dispatched to other apps.
25979918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            if (url.startsWith("about:")) {
25989918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
25999918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
2600bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
26019918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            Intent intent;
2602bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
26039918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // perform generic parsing of the URI to turn it into an Intent.
26040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
26059918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
26069918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            } catch (URISyntaxException ex) {
26079918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
26080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
26090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26115b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            // check whether the intent can be resolved. If not, we will see
26125b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            // whether we can download it from the Market.
26135b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            if (getPackageManager().resolveActivity(intent, 0) == null) {
26145b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                String packagename = intent.getPackage();
26155b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                if (packagename != null) {
26165b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    intent = new Intent(Intent.ACTION_VIEW, Uri
26175b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                            .parse("market://search?q=pname:" + packagename));
26185b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
26195b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    startActivity(intent);
26205b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    return true;
26215b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                } else {
26225b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    return false;
26235b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                }
26245b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            }
26255b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba
26269918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // sanitize the Intent, ensuring web pages can not bypass browser
26279918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // security (only access to BROWSABLE activities).
26280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.addCategory(Intent.CATEGORY_BROWSABLE);
26299918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            intent.setComponent(null);
26300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
26310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (startActivityIfNeeded(intent, -1)) {
26320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
26330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (ActivityNotFoundException ex) {
26350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // ignore the error. If no application can handle the URL,
26360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // eg about:blank, assume the browser can handle it.
26370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
26400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                openTab(url);
26410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                closeOptionsMenu();
26420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
26430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
26460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
26490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Updates the lock icon. This method is called when we discover another
26500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * resource to be loaded for this page (for example, javascript). While
26510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we update the icon type, we do not update the lock icon itself until
26520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we are done loading, it is slightly more secure this way.
26530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
26540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
26550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onLoadResource(WebView view, String url) {
26560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url != null && url.length() > 0) {
26570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // It is only if the page claims to be secure
26580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // that we may have to update the lock:
26590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mLockIconType == LOCK_ICON_SECURE) {
26600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // If NOT a 'safe' url, change the lock to mixed content!
26610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url) || URLUtil.isAboutUrl(url))) {
26620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mLockIconType = LOCK_ICON_MIXED;
266331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
26640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(LOGTAG, "BrowserActivity.updateLockIcon:" +
26650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                  " updated lock icon to " + mLockIconType + " due to " + url);
26660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
26670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
26730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show the dialog, asking the user if they would like to continue after
26740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * an excessive number of HTTP redirects.
26750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
26760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
26770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onTooManyRedirects(WebView view, final Message cancelMsg,
26780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final Message continueMsg) {
26790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
26800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameRedirect)
26810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrame307Post)
26820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
26830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
26840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        continueMsg.sendToTarget();
26850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
26860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
26870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
26880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
26890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
26900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
26910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
26920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
26930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
26940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
26950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
269737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        // Container class for the next error dialog that needs to be
269837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        // displayed.
269937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        class ErrorDialog {
270037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final int mTitle;
270137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final String mDescription;
270237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final int mError;
270337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            ErrorDialog(int title, String desc, int error) {
270437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mTitle = title;
270537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mDescription = desc;
270637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mError = error;
270737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
270837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        };
270937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
271037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void processNextError() {
271137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors == null) {
271237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                return;
271337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
271437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            // The first one is currently displayed so just remove it.
271537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            mQueuedErrors.removeFirst();
271637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors.size() == 0) {
271737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mQueuedErrors = null;
271837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                return;
271937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
272037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            showError(mQueuedErrors.getFirst());
272137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
272237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
272337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private DialogInterface.OnDismissListener mDialogListener =
272437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                new DialogInterface.OnDismissListener() {
272537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    public void onDismiss(DialogInterface d) {
272637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                        processNextError();
272737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    }
272837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                };
272937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private LinkedList<ErrorDialog> mQueuedErrors;
273037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
273137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void queueError(int err, String desc) {
273237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors == null) {
273337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mQueuedErrors = new LinkedList<ErrorDialog>();
273437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
273537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            for (ErrorDialog d : mQueuedErrors) {
273637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                if (d.mError == err) {
273737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    // Already saw a similar error, ignore the new one.
273837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    return;
273937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                }
274037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
274137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            ErrorDialog errDialog = new ErrorDialog(
27425d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    err == WebViewClient.ERROR_FILE_NOT_FOUND ?
274337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    R.string.browserFrameFileErrorLabel :
274437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    R.string.browserFrameNetworkErrorLabel,
274537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    desc, err);
274637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            mQueuedErrors.addLast(errDialog);
274737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
274837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            // Show the dialog now if the queue was empty.
274937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors.size() == 1) {
275037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                showError(errDialog);
275137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
275237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
275337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
275437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void showError(ErrorDialog errDialog) {
275537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            AlertDialog d = new AlertDialog.Builder(BrowserActivity.this)
275637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setTitle(errDialog.mTitle)
275737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setMessage(errDialog.mDescription)
275837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setPositiveButton(R.string.ok, null)
275937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .create();
276037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            d.setOnDismissListener(mDialogListener);
276137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            d.show();
276237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
276337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
27640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
27650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show a dialog informing the user of the network error reported by
27660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * WebCore.
27670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
27680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
27690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedError(WebView view, int errorCode,
27700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String description, String failingUrl) {
27715d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott            if (errorCode != WebViewClient.ERROR_HOST_LOOKUP &&
27725d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    errorCode != WebViewClient.ERROR_CONNECT &&
27735d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    errorCode != WebViewClient.ERROR_BAD_URL &&
27745d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    errorCode != WebViewClient.ERROR_UNSUPPORTED_SCHEME &&
27755d61a6c4dfb1f6e7b811f33c2a9bbe09b955293bPatrick Scott                    errorCode != WebViewClient.ERROR_FILE) {
277637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                queueError(errorCode, description);
27770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
277837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
277937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    + " " + description);
27800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We need to reset the title after an error.
27820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndRevertLockIcon();
27830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
27860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Check with the user if it is ok to resend POST data as the page they
27870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * are trying to navigate to is the result of a POST.
27880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
27890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
27900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onFormResubmission(WebView view, final Message dontResend,
27910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                       final Message resend) {
27920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
27930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameFormResubmitLabel)
27940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrameFormResubmitMessage)
27950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
27960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
27970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        resend.sendToTarget();
27980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
27990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
28000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
28010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
28020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
28030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
28040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
28050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
28060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
28070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
28080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
28110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Insert the url into the visited history database.
28120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param url The url to be inserted.
28130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param isReload True if this url is being reloaded.
28140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * FIXME: Not sure what to do when reloading the page.
28150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
28160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
28170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void doUpdateVisitedHistory(WebView view, String url,
28180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isReload) {
28190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.regionMatches(true, 0, "about:", 0, 6)) {
28200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
28210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28226b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            // remove "client" before updating it to the history so that it wont
28236b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            // show up in the auto-complete list.
28246b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            int index = url.indexOf("client=ms-");
28256b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            if (index > 0 && url.contains(".google.")) {
28266b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                int end = url.indexOf('&', index);
28276b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                if (end > 0) {
28286b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                    url = url.substring(0, index-1).concat(url.substring(end));
28296b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                } else {
28306b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                    url = url.substring(0, index-1);
28316b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba                }
28326b52a55ecd3b91ca31a0d7111f87a5d7937f215bGrace Kloba            }
28330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Browser.updateVisitedHistory(mResolver, url, true);
28340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebIconDatabase.getInstance().retainIconForPageUrl(url);
28350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
28380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Displays SSL error(s) dialog to the user.
28390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
28400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
28410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedSslError(
28420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final WebView view, final SslErrorHandler handler, final SslError error) {
28430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSettings.showSecurityWarnings()) {
28450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LayoutInflater factory =
28460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LayoutInflater.from(BrowserActivity.this);
28470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final View warningsView =
28480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    factory.inflate(R.layout.ssl_warnings, null);
28490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LinearLayout placeholder =
28500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
28510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_UNTRUSTED)) {
28530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
28540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
28550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
28560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_untrusted);
28570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
28580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_IDMISMATCH)) {
28610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
28620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
28630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
28640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_mismatch);
28650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
28660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_EXPIRED)) {
28690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
28700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
28710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
28720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_expired);
28730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
28740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_NOTYETVALID)) {
28770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
28780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
28790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
28800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_not_yet_valid);
28810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
28820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
28850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.security_warning)
28860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
28870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setView(warningsView)
28880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.ssl_continue,
28890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
28910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.proceed();
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
28930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
28940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNeutralButton(R.string.view_certificate,
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
28960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    showSSLCertificateOnError(view, handler, error);
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
28990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
29000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.cancel,
29010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
29020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
29030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
29040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
29050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
29060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
29070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setOnCancelListener(
29080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnCancelListener() {
29090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onCancel(DialogInterface dialog) {
29100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
29110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
29120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
29130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
29140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .show();
29150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed();
29170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
29210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Handles an HTTP authentication request.
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param handler The authentication handler
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param host The host
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param realm The realm
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedHttpAuthRequest(WebView view,
29290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final HttpAuthHandler handler, final String host, final String realm) {
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String username = null;
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = null;
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean reuseHttpAuthUsernamePassword =
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.useHttpAuthUsernamePassword();
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (reuseHttpAuthUsernamePassword &&
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (mTabControl.getCurrentWebView() != null)) {
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String[] credentials =
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getCurrentWebView()
29400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .getHttpAuthUsernamePassword(host, realm);
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (credentials != null && credentials.length == 2) {
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    username = credentials[0];
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    password = credentials[1];
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (username != null && password != null) {
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed(username, password);
29490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showHttpAuthentication(handler, host, realm, null, null, null, 0);
29510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
29550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
29570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only check shortcut key when MENU is held
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return getWindow().isShortcutKey(event.getKeyCode(), event);
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (view != mTabControl.getCurrentTopWebView()) {
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (event.isDown()) {
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyDown(event.getKeyCode(), event);
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyUp(event.getKeyCode(), event);
29730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebChromeClient implementation
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebChromeClient getWebChromeClient() {
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebChromeClient;
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Helper method to create a new tab or sub window.
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private void createWindow(final boolean dialog, final Message msg) {
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog) {
29890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabControl.createSubWindow();
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab t = mTabControl.getCurrentTab();
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                attachSubWindow(t);
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(t.getSubWebView());
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg.sendToTarget();
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab parent = mTabControl.getCurrentTab();
29981f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                final TabControl.Tab newTab
29991f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        = openTabAndShow(EMPTY_URL_DATA, false, null);
3000c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                if (newTab != parent) {
3001c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                    parent.addChildTab(newTab);
3002c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                }
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
30050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(mTabControl.getCurrentWebView());
30061f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                msg.sendToTarget();
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onCreateWindow(WebView view, final boolean dialog,
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final boolean userGesture, final Message resultMsg) {
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if we can't create any more tabs or sub windows.
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog && mTabControl.getCurrentSubWindow() != null) {
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_subwindows_dialog_title)
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_subwindows_dialog_message)
30190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
30220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (mTabControl.getTabCount() >= TabControl.MAX_TABS) {
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
30240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_windows_dialog_title)
30250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
30260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_windows_dialog_message)
30270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if this was a user gesture.
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (userGesture) {
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                createWindow(dialog, resultMsg);
30350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Allow the popup and create the appropriate window.
30390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener allowListener =
30400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
30410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d,
30420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                int which) {
30430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            createWindow(dialog, resultMsg);
30440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
30460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Block the popup by returning a null WebView.
30480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener blockListener =
30490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
30500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d, int which) {
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            resultMsg.sendToTarget();
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
30540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Build a confirmation dialog to display to the user.
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog d =
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.Builder(BrowserActivity.this)
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.attention)
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setMessage(R.string.popup_window_attempt)
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.allow, allowListener)
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.block, blockListener)
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setCancelable(false)
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .create();
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Show the confirmation dialog.
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d.show();
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onCloseWindow(WebView window) {
30731f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            final TabControl.Tab current = mTabControl.getCurrentTab();
30741f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins            final TabControl.Tab parent = current.getParentTab();
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // JavaScript can only close popup window.
30771f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                switchToTab(mTabControl.getTabIndex(parent));
30781f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                // Now we need to close the window
30791f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                closeTab(current);
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onProgressChanged(WebView view, int newProgress) {
308568579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            mTitleBar.setProgress(newProgress);
30863bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            if (mFakeTitleBar != null) {
30873bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins                mFakeTitleBar.setProgress(newProgress);
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (newProgress == 100) {
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // onProgressChanged() is called for sub-frame too while
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // onPageFinished() is only called for the main frame. sync
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // cookie and cache promptly here.
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CookieSyncManager.getInstance().sync();
3095cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                if (mInLoad) {
3096cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    mInLoad = false;
3097cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    updateInLoadMenuItems();
3098a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    // If the options menu is open, leave the title bar
3099a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    if (!mOptionsMenuOpen || !mIconView) {
3100a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                        hideFakeTitleBar();
3101a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    }
3102cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
3103a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins            } else if (!mInLoad) {
3104cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // onPageFinished may have already been called but a subframe
3105cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // is still loading and updating the progress. Reset mInLoad
3106cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // and update the menu items.
3107a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                mInLoad = true;
3108a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                updateInLoadMenuItems();
3109184f5e351dd511e6dc41ba8468565c14d6beb4f5Leon Scroggins                if (!mOptionsMenuOpen || mIconView) {
3110a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    // This page has begun to load, so show the title bar
3111a27ff19e24cb1c9fef5624dbc4554548349b5b31Leon Scroggins                    showFakeTitleBar();
3112cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedTitle(WebView view, String title) {
3118598c9ccf8641e0e4563bba2fd5613bcb4de766ecPatrick Scott            String url = view.getUrl();
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // here, if url is null, we want to reset the title
312168579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins            setUrlTitle(url, title);
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url == null ||
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url.length() >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
31260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3127fce182bff7713a12714018327f6da9500011ab17Leon Scroggins            // See if we can find the current url in our history database and
3128fce182bff7713a12714018327f6da9500011ab17Leon Scroggins            // add the new title to it.
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith("http://www.")) {
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(11);
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (url.startsWith("http://")) {
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(4);
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = "%" + url;
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String [] selArgs = new String[] { url };
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String where = Browser.BookmarkColumns.URL + " LIKE ? AND "
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + Browser.BookmarkColumns.BOOKMARK + " = 0";
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Browser.HISTORY_PROJECTION, where, selArgs, null);
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (c.moveToFirst()) {
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Current implementation of database only has one entry per
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // url.
3145fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    ContentValues map = new ContentValues();
3146fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    map.put(Browser.BookmarkColumns.TITLE, title);
3147fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    mResolver.update(Browser.BOOKMARKS_URI, map,
3148fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                            "_id = " + c.getInt(0), null);
31490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.close();
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IllegalStateException e) {
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "BrowserActivity onReceived title", e);
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (SQLiteException ex) {
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "onReceivedTitle() caught SQLiteException: ", ex);
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedIcon(WebView view, Bitmap icon) {
31603918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            updateIcon(view, icon);
31613918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        }
31623918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott
31633918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        @Override
316459ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott        public void onReceivedTouchIconUrl(WebView view, String url,
316559ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                boolean precomposed) {
31663918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            final ContentResolver cr = getContentResolver();
31673918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            final Cursor c =
31683918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                    BrowserBookmarksAdapter.queryBookmarksForUrl(cr,
3169a5d669e4c08f0e64387c2c539c41a26ac8c845abLeon Scroggins                            view.getOriginalUrl(), view.getUrl(), true);
31703918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            if (c != null) {
31713918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                if (c.getCount() > 0) {
317259ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    // Let precomposed icons take precedence over non-composed
317359ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    // icons.
317459ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    if (precomposed && mTouchIconLoader != null) {
317559ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                        mTouchIconLoader.cancel(false);
317659ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                        mTouchIconLoader = null;
317759ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    }
317859ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    // Have only one async task at a time.
317959ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    if (mTouchIconLoader == null) {
318059ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                        mTouchIconLoader = new DownloadTouchIcon(
318159ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                                BrowserActivity.this, cr, c, view);
318259ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                        mTouchIconLoader.execute(url);
318359ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott                    }
31843918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                } else {
31853918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                    c.close();
31863918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott                }
31873918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott            }
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3189092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
3190adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        @Override
3191c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu        public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
3192adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            if (mCustomView != null)
3193adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                return;
3194adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3195adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Add the custom view to its container.
3196adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
3197adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomView = view;
3198c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomViewCallback = callback;
3199adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Save the menu state and set it to empty while the custom
3200adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // view is showing.
3201adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mOldMenuState = mMenuState;
3202adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mMenuState = EMPTY_MENU;
3203c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            // Hide the content view.
3204c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mContentView.setVisibility(View.GONE);
3205adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Finally show the custom view container.
3206c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomViewContainer.setVisibility(View.VISIBLE);
3207c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomViewContainer.bringToFront();
3208adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        }
3209adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3210adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        @Override
3211adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        public void onHideCustomView() {
3212adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            if (mCustomView == null)
3213adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                return;
3214adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3215c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            // Hide the custom view.
3216c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomView.setVisibility(View.GONE);
3217adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Remove the custom view from its container.
3218adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer.removeView(mCustomView);
3219adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomView = null;
3220adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Reset the old menu state.
3221adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mMenuState = mOldMenuState;
3222adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mOldMenuState = EMPTY_MENU;
3223adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer.setVisibility(View.GONE);
3224c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mCustomViewCallback.onCustomViewHidden();
3225c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            // Show the content view.
3226c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu            mContentView.setVisibility(View.VISIBLE);
3227adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        }
3228adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3229092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        /**
323079e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * The origin has exceeded its database quota.
3231092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param url the URL that exceeded the quota
3232092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param databaseIdentifier the identifier of the database on
3233092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         *     which the transaction that caused the quota overflow was run
3234092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param currentQuota the current quota for the origin.
323525a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch         * @param estimatedSize the estimated size of the database.
323679e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * @param totalUsedQuota is the sum of all origins' quota.
3237092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param quotaUpdater The callback to run when a decision to allow or
3238092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         *     deny quota has been made. Don't forget to call this!
3239092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         */
3240092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        @Override
3241092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        public void onExceededDatabaseQuota(String url,
324225a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch            String databaseIdentifier, long currentQuota, long estimatedSize,
324325a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
324479e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu            mSettings.getWebStorageSizeManager().onExceededDatabaseQuota(
324525a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch                    url, databaseIdentifier, currentQuota, estimatedSize,
324625a1523642bead2f7e7f929ba9d6d1143dce06a0Ben Murdoch                    totalUsedQuota, quotaUpdater);
324779e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu        }
324879e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu
324979e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu        /**
325079e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * The Application Cache has exceeded its max size.
325179e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * @param spaceNeeded is the amount of disk space that would be needed
325279e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * in order for the last appcache operation to succeed.
325379e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * @param totalUsedQuota is the sum of all origins' quota.
325479e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * @param quotaUpdater A callback to inform the WebCore thread that a new
325579e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * app cache size is available. This callback must always be executed at
325679e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         * some point to ensure that the sleeping WebCore thread is woken up.
325779e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu         */
325879e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu        @Override
325979e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu        public void onReachedMaxAppCacheSize(long spaceNeeded,
326079e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
326179e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu            mSettings.getWebStorageSizeManager().onReachedMaxAppCacheSize(
326279e82b7ba72a7278911edf0dd7b03c65c4ec0e9dAndrei Popescu                    spaceNeeded, totalUsedQuota, quotaUpdater);
3263092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        }
32647db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch
32652bc69918d97a767a02132090e58718077381ba1aSteve Block        /**
32662bc69918d97a767a02132090e58718077381ba1aSteve Block         * Instructs the browser to show a prompt to ask the user to set the
32672bc69918d97a767a02132090e58718077381ba1aSteve Block         * Geolocation permission state for the specified origin.
32682bc69918d97a767a02132090e58718077381ba1aSteve Block         * @param origin The origin for which Geolocation permissions are
32692bc69918d97a767a02132090e58718077381ba1aSteve Block         *     requested.
32702bc69918d97a767a02132090e58718077381ba1aSteve Block         * @param callback The callback to call once the user has set the
32712bc69918d97a767a02132090e58718077381ba1aSteve Block         *     Geolocation permission state.
32722bc69918d97a767a02132090e58718077381ba1aSteve Block         */
32732bc69918d97a767a02132090e58718077381ba1aSteve Block        @Override
32742bc69918d97a767a02132090e58718077381ba1aSteve Block        public void onGeolocationPermissionsShowPrompt(String origin,
32752bc69918d97a767a02132090e58718077381ba1aSteve Block                GeolocationPermissions.Callback callback) {
32762bc69918d97a767a02132090e58718077381ba1aSteve Block            mTabControl.getCurrentTab().getGeolocationPermissionsPrompt().show(
32772bc69918d97a767a02132090e58718077381ba1aSteve Block                    origin, callback);
32782bc69918d97a767a02132090e58718077381ba1aSteve Block        }
32792bc69918d97a767a02132090e58718077381ba1aSteve Block
32802bc69918d97a767a02132090e58718077381ba1aSteve Block        /**
32812bc69918d97a767a02132090e58718077381ba1aSteve Block         * Instructs the browser to hide the Geolocation permissions prompt.
32822bc69918d97a767a02132090e58718077381ba1aSteve Block         */
32832bc69918d97a767a02132090e58718077381ba1aSteve Block        @Override
32842bc69918d97a767a02132090e58718077381ba1aSteve Block        public void onGeolocationPermissionsHidePrompt() {
32852bc69918d97a767a02132090e58718077381ba1aSteve Block            mTabControl.getCurrentTab().getGeolocationPermissionsPrompt().hide();
32862bc69918d97a767a02132090e58718077381ba1aSteve Block        }
32872bc69918d97a767a02132090e58718077381ba1aSteve Block
32887db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        /* Adds a JavaScript error message to the system log.
32897db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param message The error message to report.
32907db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param lineNumber The line number of the error.
32917db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param sourceID The name of the source file that caused the error.
32927db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         */
32937db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        @Override
32947db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        public void addMessageToConsole(String message, int lineNumber, String sourceID) {
3295bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(true);
3296bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            errorConsole.addErrorMessage(message, sourceID, lineNumber);
3297bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                if (mShouldShowErrorConsole &&
3298bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                        errorConsole.getShowState() != ErrorConsoleView.SHOW_MAXIMIZED) {
3299bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                    errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
3300bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                }
3301bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            Log.w(LOGTAG, "Console: " + message + " " + sourceID + ":" + lineNumber);
33027db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        }
3303540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
3304540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        /**
3305540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * Ask the browser for an icon to represent a <video> element.
3306540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * This icon will be used if the Web page did not specify a poster attribute.
3307540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         *
3308540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * @return Bitmap The icon or null if no such icon is available.
3309540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * @hide pending API Council approval
3310540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         */
3311540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        @Override
3312540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        public Bitmap getDefaultVideoPoster() {
3313540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            if (mDefaultVideoPoster == null) {
3314540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu                mDefaultVideoPoster = BitmapFactory.decodeResource(
3315540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu                        getResources(), R.drawable.default_video_poster);
3316540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            }
3317540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            return mDefaultVideoPoster;
3318540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
3319540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
3320540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        /**
3321540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * Ask the host application for a custom progress view to show while
3322540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * a <video> is loading.
3323540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         *
3324540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * @return View The progress view.
3325540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         * @hide pending API Council approval
3326540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu         */
3327540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        @Override
3328540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        public View getVideoLoadingProgressView() {
3329540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            if (mVideoProgressView == null) {
3330540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu                LayoutInflater inflater = LayoutInflater.from(BrowserActivity.this);
3331540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu                mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
3332540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            }
3333540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu            return mVideoProgressView;
3334540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu        }
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
3351e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                || !contentDisposition.regionMatches(
3352e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        true, 0, "attachment", 0, 10)) {
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
3357e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            ResolveInfo info = getPackageManager().resolveActivity(intent,
3358e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    PackageManager.MATCH_DEFAULT_ONLY);
3359e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott            if (info != null) {
3360e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                ComponentName myName = getComponentName();
3361e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // If we resolved to ourselves, we don't want to attempt to
3362e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                // load the url only to try and download it again.
3363e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                if (!myName.getPackageName().equals(
3364e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        info.activityInfo.packageName)
3365e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        || !myName.getClassName().equals(
3366e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                info.activityInfo.name)) {
3367e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // someone (other than us) knows how to handle this mime
3368e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    // type with this scheme, don't download.
3369e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    try {
3370e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        startActivity(intent);
3371e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        return;
3372e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                    } catch (ActivityNotFoundException ex) {
3373e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        if (LOGD_ENABLED) {
3374e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                            Log.d(LOGTAG, "activity not found for " + mimetype
3375e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    + " over " + Uri.parse(url).getScheme(),
3376e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                                    ex);
3377e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        }
3378e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // Best behavior is to fall back to a download in this
3379e1fb96676cd2404c5de091d60828185228ef4c90Patrick Scott                        // case
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // java.net.URI is a lot stricter than KURL so we have to undo
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // KURL's percent-encoding and redo the encoding using java.net.URI.
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        URI uri = null;
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Undo the percent-encoding that KURL may have done.
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String newUrl = new String(URLUtil.decode(url.getBytes()));
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Parse the url into pieces
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebAddress w = new WebAddress(newUrl);
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String frag = null;
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String query = null;
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String path = w.mPath;
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Break the path into path, query, and fragment
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (path.length() > 0) {
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Strip the fragment
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int idx = path.lastIndexOf('#');
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    frag = path.substring(idx + 1);
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                idx = path.lastIndexOf('?');
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query = path.substring(idx + 1);
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query, frag);
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
34633dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_URI, uri.toString());
34643dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_COOKIE_DATA, cookies);
34653dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_USER_AGENT, userAgent);
34663dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_NOTIFICATION_PACKAGE,
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
34683dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_NOTIFICATION_CLASS,
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class.getCanonicalName());
34703dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_VISIBILITY, Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
34713dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_MIME_TYPE, mimetype);
34723dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_FILE_NAME_HINT, filename);
34733dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_DESCRIPTION, uri.getHost());
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
34753dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru            values.put(Downloads.COLUMN_TOTAL_BYTES, contentLength);
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getContentResolver().insert(Downloads.CONTENT_URI, values);
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            viewDownloads(contentUri);
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        saveLockIcon();
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = LOCK_ICON_UNSECURE;
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (URLUtil.isHttpsUrl(url)) {
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mLockIconType = LOCK_ICON_SECURE;
350031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                      " reset lock icon to " + mLockIconType);
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3509eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    /* package */ void setLockIconType(int type) {
3510eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        mLockIconType = type;
3511eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    }
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3513eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    /* package */ int getLockIconType() {
3514eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        return mLockIconType;
3515eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    }
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3517eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    /* package */ void setPrevLockType(int type) {
3518eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        mPrevLockType = type;
3519eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    }
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3521eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    /* package */ int getPrevLockType() {
3522eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba        return mPrevLockType;
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35263bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     * Update the lock icon to correspond to our latest state.
35273bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins     */
35283bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /* package */ void updateLockIconToLatest() {
35293bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        updateLockIconImage(mLockIconType);
35303bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    }
35313bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins
35323bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins    /**
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
35340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
354268579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins        mTitleBar.setLock(d);
35433bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins        if (mFakeTitleBar != null) {
35443bbb6caa3ceaec1106fe1de76066f5e1a186795eLeon Scroggins            mFakeTitleBar.setLock(d);
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showPageInfo(final TabControl.Tab tab,
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
35730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
35750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
35770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
35780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
35810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
35820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoFromShowSSLCertificateOnError = new Boolean(fromShowSSLCertificateOnError);
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
36000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
36100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
36120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
36200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
36240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
36250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
36260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
36370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificate(final TabControl.Tab tab) {
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
37000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
37010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
37020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
37070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
37080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
37090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
37100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
37110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
37120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
37140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
37150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
37160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
37170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
37210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
37220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
37230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
37240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificateOnError(
37270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
37360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
37380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
37390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
37420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
37450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
37480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
37490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
37500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
37510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
37520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
37550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
37560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
37570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
37580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
37590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
37620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
37630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
37640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
37650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
37660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
37690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
37700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
37710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
37720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
37730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
37740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
37750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
37760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
37770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
37780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
37790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
37800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
37810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
37820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
37830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
37840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
37860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
37870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
37880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
37890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
37900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
37910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
37920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
37930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
37940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
37960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
37970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
37980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
38000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
38010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
38020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
38030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
38040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
38050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
38060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
38070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
38090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
38130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
38140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
38150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
38160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
38210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
38240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
38340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
38400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
38410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
38420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
38430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
38490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String issuedOn = reformatCertificateDate(
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotBefore());
38600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
38610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String expiresOn = reformatCertificateDate(
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotAfter());
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Re-formats the certificate date (Date.toString()) string to
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * a properly localized date string.
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the original certificate date string if fails to localize.
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the original string is null, returns an empty string "".
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String reformatCertificateDate(String certificateDate) {
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      String reformattedDate = null;
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if (certificateDate != null) {
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Date date = null;
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = java.text.DateFormat.getInstance().parse(certificateDate);
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (ParseException e) {
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = null;
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (date != null) {
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              reformattedDate =
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  DateFormat.getDateFormat(this).format(date);
38930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
38950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return reformattedDate != null ? reformattedDate :
38970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          (certificateDate != null ? certificateDate : "");
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showHttpAuthentication(final HttpAuthHandler handler,
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
39200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
39280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
39380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
39390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
39400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
39410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
39430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
39440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
39450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
39470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
39480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
39490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
39500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
39520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
39530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
39550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
39560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
39570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
39580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
39590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
39600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
39610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
39620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
39630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
39640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
39650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
39660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
39670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
39680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
39700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
39730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
39740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
39750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
39760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
39770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
39780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
39820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
39830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
39840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
39850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
39860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
39870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
39880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
39890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
39910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
39920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
39930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
39940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
39950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
39960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
40010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
40020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
40040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
40050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
40060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
40070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
40080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
40090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
40100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
40110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
40120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
40130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
4014eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            if (mInLoad) {
4015eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                createAndShowNetworkDialog();
4016eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott           }
40170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
40190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
40200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
40210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4024eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // This method shows the network dialog alerting the user that the net is
4025eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    // down. It will only show the dialog if mAlertDialog is null.
4026eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    private void createAndShowNetworkDialog() {
4027eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        if (mAlertDialog == null) {
4028eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott            mAlertDialog = new AlertDialog.Builder(this)
4029eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setTitle(R.string.loadSuspendedTitle)
4030eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setMessage(R.string.loadSuspended)
4031eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .setPositiveButton(R.string.ok, null)
4032eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott                    .show();
4033eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott        }
4034eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott    }
4035eb6ab2aeeccb5ddfba7faefd9c1b5fe14ee8d885Patrick Scott
40360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
40370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
40380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
40390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
40400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
40410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
40420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
40430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
40440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
404525d3547e0df084f963e38c6a93c99b02bd619de3Leon Scroggins                        openTab(data);
40460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
40470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final TabControl.Tab currentTab =
40480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
40491f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        dismissSubWindow(currentTab);
40501f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                        if (data != null && data.length() != 0) {
40511f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins                            getTopWindow().loadUrl(data);
40520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
40530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
40540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
40550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
40560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
40570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
40580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4059304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        getTopWindow().requestFocus();
40600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
40630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
40640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * menu to see the download window, or when a download changes state. It
40650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * shows the download window ontop of the current window.
40660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void viewDownloads(Uri downloadRecord) {
40680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
40690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
40700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
40710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, this.DOWNLOAD_PAGE);
40720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4075160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins    /**
4076160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * Open the Go page.
4077160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     * @param startWithHistory If true, open starting on the history tab.
4078160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     *                         Otherwise, start with the bookmarks tab.
4079160a7e7d27755b7a3715ad87735b8070ab64d58aLeon Scroggins     */
4080304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
40810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
40820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
40830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
40840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
40860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
40870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
40880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
4089dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        Bitmap thumbnail = createScreenshot(current);
4090dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch
40910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
40920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
40930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
40940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
40950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
40960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
40970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
40980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
40990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
41010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
41020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
41030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
41050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
4106dcc2b6f08dd5677bc6ba761a9ba6f1c655113051Ben Murdoch        intent.putExtra("thumbnail", thumbnail);
4107304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        // Disable opening in a new window if we have maxed out the windows
4108304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins        intent.putExtra("disable_new_window", mTabControl.getTabCount()
4109304442375719effd41dbd53ae62de7a8d0cec7d9Leon Scroggins                >= TabControl.MAX_TABS);
41103918d4443ff38ef1870e02aa51a8b29f8352bb1aPatrick Scott        intent.putExtra("touch_icon_url", current.getTouchIconUrl());
41110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
41120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
41130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
41140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
41160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
41190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void loadURL(WebView view, String url) {
41200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
41210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
41220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
41230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mWebViewClient.shouldOverrideUrlLoading(view, url)) {
41240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                view.loadUrl(url);
41250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
41260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
41300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
41310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
41320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
41340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get window count
41380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    int getWindowCount(){
41400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if(mTabControl != null){
41410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getTabCount();
41420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
41430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return 0;
41440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4146b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
41470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
41480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
41490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
415025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
41510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
41520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
41530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
41550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
41560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
41570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
41580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
41590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
41600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
41610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
41620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
41630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
41640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
41650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
41670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
41680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
41700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
41710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
41720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
41730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
41740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
4175123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
4176123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
4177123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
4178123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
41790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
41800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
41810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
4183565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
4184565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
4185565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
4186565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
4187565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
4188565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
4189565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
4190565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
419147fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
4192565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
4193565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
4194565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
4195565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
4196565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
41970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
4198565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
41990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
42000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
42010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
42020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Regex.WEB_URL_PATTERN.matcher(inUrl).matches()) {
42030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
42040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
42050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
420847fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
42090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4211bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    /* package */ void setShouldShowErrorConsole(boolean flag) {
4212bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag == mShouldShowErrorConsole) {
4213bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Nothing to do.
4214bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return;
4215bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
4216bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4217bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        mShouldShowErrorConsole = flag;
4218bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4219bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        ErrorConsoleView errorConsole = mTabControl.getCurrentErrorConsole(true);
4220bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4221bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        if (flag) {
4222bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Setting the show state of the console will cause it's the layout to be inflated.
4223bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            if (errorConsole.numberOfErrors() > 0) {
4224bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_MINIMIZED);
4225bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            } else {
4226bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                errorConsole.showConsole(ErrorConsoleView.SHOW_NONE);
4227bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            }
4228bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4229bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            // Now we can add it to the main view.
4230bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.addView(errorConsole,
4231bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
4232bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch                                                  ViewGroup.LayoutParams.WRAP_CONTENT));
4233bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        } else {
4234bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            mErrorConsoleContainer.removeView(errorConsole);
4235bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch        }
4236bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4237bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    }
4238bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
4239eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_UNSECURE = 0;
4240eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_SECURE   = 1;
4241eb6eef4c45df2d65c3e70660493a147a2be405e3Grace Kloba    final static int LOCK_ICON_MIXED    = 2;
42420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mLockIconType = LOCK_ICON_UNSECURE;
42440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mPrevLockType = LOCK_ICON_UNSECURE;
42450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
42470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
42480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
42490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
4250adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
4251adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
4252c9b5556351b59caec77b4eec1ad30652fec6a4d9Andrei Popescu    private WebChromeClient.CustomViewCallback mCustomViewCallback;
42530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
42550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
42560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
42570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
4258adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
42590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
42600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
42610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
42630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
42640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
42650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
42660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
42680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
42690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mPageStarted;
42710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mActivityInPause = true;
42720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
42740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
42760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
42780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
42790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
42800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
42810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
42820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
42830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
42840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
42850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
42860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
42870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
42880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
42900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
42910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
42920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
42930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
42940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
42950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
42970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
42990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
43000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
43020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
43030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wait for credentials before loading google.com
43050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ProgressDialog mCredsDlg;
43060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
43080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
43090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
43100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
43110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
43120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
43140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
43150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
43160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mPageInfoView;
43170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
43180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
43190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
43200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Boolean mPageInfoFromShowSSLCertificateOnError;
43210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
43230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
43240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
43250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
43260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
43270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
43280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
43300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
43310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
43320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mSSLCertificateView;
43330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
43350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
43360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
43370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
43380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
43400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
43410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT,
43420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT);
4343adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
4344adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
4345adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            ViewGroup.LayoutParams.FILL_PARENT,
4346adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            ViewGroup.LayoutParams.FILL_PARENT,
4347adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
434847fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
434947fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
43500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
43510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
43520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
43530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
43540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
43550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
43560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
43580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
43600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
43610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
43620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
43630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
43640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
43650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
43660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
43670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
43680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
43690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
43710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
43730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
43750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
43760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
43780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
437968579393973f745fc65a2781061af9bb8f2d7020Leon Scroggins    private TitleBar mTitleBar;
438081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
4381bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private LinearLayout mErrorConsoleContainer = null;
4382bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch    private boolean mShouldShowErrorConsole = false;
4383bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch
43840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
43850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
43860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
43870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
43880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
43890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
43900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
43920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
43930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
43940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4395b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
4396b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
439759ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott    // AsyncTask for downloading touch icons
439859ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott    /* package */ DownloadTouchIcon mTouchIconLoader;
439959ce830c6eab58171b727abe5282c4abadb1a040Patrick Scott
44000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
440178a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
440278a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
440378a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
44040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4405540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the default <video> poster
4406540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private Bitmap mDefaultVideoPoster;
4407540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    // the video progress view
4408540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu    private View mVideoProgressView;
4409540035dfd1347c78eeec10ec0847e18fcc50ef36Andrei Popescu
441025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
441125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
441225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
441325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
441425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class UrlData {
441525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mUrl;
441660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        byte[] mPostData;
441760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
441825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
441925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
442025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
442160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
442260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        void setPostData(byte[] postData) {
442360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            mPostData = postData;
442460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
442560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
442625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
442725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            return mUrl == null || mUrl.length() == 0;
442825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
442925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
44307944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        public void loadIn(WebView webView) {
443160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            if (mPostData != null) {
443260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                webView.postUrl(mUrl, mPostData);
443360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            } else {
443460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                webView.loadUrl(mUrl);
443560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            }
443625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
443725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
443825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
443925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
444025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A subclass of UrlData class that can display inlined content using
444125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * {@link WebView#loadDataWithBaseURL(String, String, String, String, String)}.
444225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
444325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class InlinedUrlData extends UrlData {
444425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        InlinedUrlData(String inlined, String mimeType, String encoding, String failUrl) {
444525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            super(failUrl);
444625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mInlined = inlined;
444725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mMimeType = mimeType;
444825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mEncoding = encoding;
444925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
445025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mMimeType;
445125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mInlined;
445225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mEncoding;
44537944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        @Override
445425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
4455bff2d603c022691237c31d9a57ad8c217c6e7e11Ben Murdoch            return mInlined == null || mInlined.length() == 0 || super.isEmpty();
445625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
445725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
44587944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        @Override
44597944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        public void loadIn(WebView webView) {
446025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            webView.loadDataWithBaseURL(null, mInlined, mMimeType, mEncoding, mUrl);
446125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
446225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    }
446325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
44641f005d370557b6e69d2de6537e5ea21f73a7ec3fLeon Scroggins    /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
44650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
4466