BrowserActivity.java revision cc63403643786905262f505ab5266d8e80b9924c
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.ActivityManager;
240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.AlertDialog;
250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.ProgressDialog;
260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.SearchManager;
270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ActivityNotFoundException;
280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.BroadcastReceiver;
290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ComponentName;
300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentResolver;
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;
380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.PackageManager;
390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.ResolveInfo;
400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.AssetManager;
410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Configuration;
420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Resources;
430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.Cursor;
440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.sqlite.SQLiteDatabase;
450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.sqlite.SQLiteException;
460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Color;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.DrawFilter;
500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Paint;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.PaintFlagsDrawFilter;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.BitmapDrawable;
540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.LayerDrawable;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.PaintDrawable;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.hardware.SensorListener;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.hardware.SensorManager;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.EventHandler;
630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.IBinder;
710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.RemoteException;
750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.ServiceManager;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Contacts;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Contacts.Intents.Insert;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.IClipboard;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.util.Regex;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.AlphaAnimation;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.Animation;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.AnimationSet;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.DecelerateInterpolator;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.ScaleAnimation;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.TranslateAnimation;
1060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
1070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
1080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
1090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
1100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
1110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
1120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
1130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
1140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
1150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebViewClient;
1170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
1220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.BufferedOutputStream;
1240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.FileInputStream;
1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.FileOutputStream;
1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.IOException;
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.InputStream;
1290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URI;
1319918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.text.ParseException;
1350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Enumeration;
1370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
138a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scottimport java.util.LinkedList;
1390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Vector;
1400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.zip.ZipEntry;
1430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.zip.ZipFile;
1440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
1460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    implements KeyTracker.OnKeyTracker,
1470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View.OnCreateContextMenuListener,
1480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        DownloadListener {
1490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
15131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
15231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
15331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
15431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
15531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
15631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
1570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IGoogleLoginService mGls = null;
1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ServiceConnection mGlsConnection = null;
1590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SensorManager mSensorManager = null;
1610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
162565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
163565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
164565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
165565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
166565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
167565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
168565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* Whitelisted webpages
1700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static HashSet<String> sWhiteList;
1710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    static {
1730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList = new HashSet<String>();
1740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("cnn.com/");
1750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("espn.go.com/");
1760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("nytimes.com/");
1770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("engadget.com/");
1780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("yahoo.com/");
1790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("msn.com/");
1800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("amazon.com/");
1810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("consumerist.com/");
1820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("google.com/m/news");
1830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
1840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    */
1850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setupHomePage() {
1870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Runnable getAccount = new Runnable() {
1880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void run() {
1890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Lower priority
1900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // get the default home page
1920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String homepage = mSettings.getHomePage();
1930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
1950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mGls == null) return;
1960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
197f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                    if (!homepage.startsWith("http://www.google.")) return;
198f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                    if (homepage.indexOf('?') == -1) return;
199f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba
2000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String hostedUser = mGls.getAccount(GoogleLoginServiceConstants.PREFER_HOSTED);
2010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String googleUser = mGls.getAccount(GoogleLoginServiceConstants.REQUIRE_GOOGLE);
2020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // three cases:
2040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser == googleUser
2060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has only a google account
2070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser != googleUser
2090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has a hosted account and a google account
2100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser != null, googleUser == null
2120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has only a hosted account (so far)
2130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // developers might have no accounts at all
2150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (hostedUser == null) return;
2160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (googleUser == null || !hostedUser.equals(googleUser)) {
2180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
219f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                        homepage = homepage.replace("?", "/a/" + domain + "?");
2200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
2210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (RemoteException ignore) {
2220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Login service died; carry on
2230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (RuntimeException ignore) {
2240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Login service died; carry on
2250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } finally {
2260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    finish(homepage);
2270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            private void finish(final String homepage) {
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.post(new Runnable() {
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void run() {
2330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mSettings.setHomePage(BrowserActivity.this, homepage);
2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        resumeAfterCredentials();
2350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // as this is running in a separate thread,
2370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // BrowserActivity's onDestroy() may have been called,
2380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // which also calls unbindService().
2390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (mGlsConnection != null) {
2400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // we no longer need to keep GLS open
2410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            unbindService(mGlsConnection);
2420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mGlsConnection = null;
2430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } });
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } };
2460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final boolean[] done = { false };
2480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open a connection to the Google Login Service.  The first
2500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // time the connection is established, set up the homepage depending on
2510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the account in a background thread.
2520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mGlsConnection = new ServiceConnection() {
2530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void onServiceConnected(ComponentName className, IBinder service) {
2540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mGls = IGoogleLoginService.Stub.asInterface(service);
2550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (done[0] == false) {
2560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    done[0] = true;
2570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Thread account = new Thread(getAccount);
2580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    account.setName("GLSAccount");
2590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    account.start();
2600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void onServiceDisconnected(ComponentName className) {
2630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mGls = null;
2640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        };
2660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bindService(GoogleLoginServiceConstants.SERVICE_INTENT,
2680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mGlsConnection, Context.BIND_AUTO_CREATE);
2690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
2720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This class is in charge of installing pre-packaged plugins
2730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * from the Browser assets directory to the user's data partition.
2740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Plugins are loaded from the "plugins" directory in the assets;
2750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Anything that is in this directory will be copied over to the
2760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * user data partition in app_plugins.
2770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
2780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class CopyPlugins implements Runnable {
2790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String TAG = "PluginsInstaller";
2800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String ZIP_FILTER = "assets/plugins/";
2810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String APK_PATH = "/system/app/Browser.apk";
2820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String PLUGIN_EXTENSION = ".so";
2830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String TEMPORARY_EXTENSION = "_temp";
2840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String BUILD_INFOS_FILE = "build.prop";
2850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String SYSTEM_BUILD_INFOS_FILE = "/system/"
2860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              + BUILD_INFOS_FILE;
2870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int BUFSIZE = 4096;
2880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean mDoOverwrite = false;
2890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String pluginsPath;
2900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Context mContext;
2910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        File pluginsDir;
2920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AssetManager manager;
2930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public CopyPlugins (boolean overwrite, Context context) {
2950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mDoOverwrite = overwrite;
2960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContext = context;
2970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Returned a filtered list of ZipEntry.
3010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We list all the files contained in the zip and
3020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * only returns the ones starting with the ZIP_FILTER
3030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * path.
3040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
3050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param zip the zip file used.
3060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Vector<ZipEntry> pluginsFilesFromZip(ZipFile zip) {
3080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Vector<ZipEntry> list = new Vector<ZipEntry>();
3090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Enumeration entries = zip.entries();
3100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            while (entries.hasMoreElements()) {
3110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ZipEntry entry = (ZipEntry) entries.nextElement();
3120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (entry.getName().startsWith(ZIP_FILTER)) {
3130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  list.add(entry);
3140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return list;
3170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Utility method to copy the content from an inputstream
3210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * to a file output stream.
3220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void copyStreams(InputStream is, FileOutputStream fos) {
3240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BufferedOutputStream os = null;
3250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
3260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                byte data[] = new byte[BUFSIZE];
3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int count;
3280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                os = new BufferedOutputStream(fos, BUFSIZE);
3290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                while ((count = is.read(data, 0, BUFSIZE)) != -1) {
3300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    os.write(data, 0, count);
3310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                os.flush();
3330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IOException e) {
3340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "Exception while copying: " + e);
3350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } finally {
3360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              try {
3370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (os != null) {
3380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    os.close();
3390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              } catch (IOException e2) {
3410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "Exception while closing the stream: " + e2);
3420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
3430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Returns a string containing the contents of a file
3480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
3490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param file the target file
3500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String contentsOfFile(File file) {
3520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          String ret = null;
3530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          FileInputStream is = null;
3540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
3550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            byte[] buffer = new byte[BUFSIZE];
3560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int count;
3570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            is = new FileInputStream(file);
3580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            StringBuffer out = new StringBuffer();
3590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            while ((count = is.read(buffer, 0, BUFSIZE)) != -1) {
3610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              out.append(new String(buffer, 0, count));
3620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ret = out.toString();
3640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (IOException e) {
3650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exception getting contents of file " + e);
3660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } finally {
3670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (is != null) {
3680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              try {
3690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                is.close();
3700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              } catch (IOException e2) {
3710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "Exception while closing the file: " + e2);
3720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
3730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
3750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          return ret;
3760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Utility method to initialize the user data plugins path.
3800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void initPluginsPath() {
3820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BrowserSettings s = BrowserSettings.getInstance();
3830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            pluginsPath = s.getPluginsPath();
3840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (pluginsPath == null) {
3850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                s.loadFromDb(mContext);
3860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                pluginsPath = s.getPluginsPath();
3870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
38831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
3890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(TAG, "Plugin path: " + pluginsPath);
3900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Utility method to delete a file or a directory
3950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
3960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param file the File to delete
3970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void deleteFile(File file) {
3990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File[] files = file.listFiles();
4000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((files != null) && files.length > 0) {
4010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              for (int i=0; i< files.length; i++) {
4020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                deleteFile(files[i]);
4030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
4040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!file.delete()) {
4060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              Log.e(TAG, file.getPath() + " could not get deleted");
4070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Clean the content of the plugins directory.
4120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We delete the directory, then recreate it.
4130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void cleanPluginsDirectory() {
41531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort          if (LOGV_ENABLED) {
4160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(TAG, "delete plugins directory: " + pluginsPath);
4170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          File pluginsDirectory = new File(pluginsPath);
4190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          deleteFile(pluginsDirectory);
4200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          pluginsDirectory.mkdir();
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Copy the SYSTEM_BUILD_INFOS_FILE file containing the
4260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * informations about the system build to the
4270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * BUILD_INFOS_FILE in the plugins directory.
4280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void copyBuildInfos() {
4300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
43131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              Log.v(TAG, "Copy build infos to the plugins directory");
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
4350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE);
4360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyStreams(new FileInputStream(buildInfoFile),
4370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new FileOutputStream(buildInfoPlugins));
4380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (IOException e) {
4390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exception while copying the build infos: " + e);
4400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
4410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Returns true if the current system is newer than the
4450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * system that installed the plugins.
4460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We determinate this by checking the build number of the system.
4470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
4480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * At the end of the plugins copy operation, we copy the
4490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * SYSTEM_BUILD_INFOS_FILE to the BUILD_INFOS_FILE.
4500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We then just have to load both and compare them -- if they
4510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * are different the current system is newer.
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
4530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Loading and comparing the strings should be faster than
4540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * creating a hash, the files being rather small. Extracting the
4550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * version number would require some parsing which may be more
4560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * brittle.
4570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean newSystemImage() {
4590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
4600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
4610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE);
4620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!buildInfoPlugins.exists()) {
46331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort              if (LOGV_ENABLED) {
4640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(TAG, "build.prop in plugins directory " + pluginsPath
4650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  + " does not exist, therefore it's a new system image");
4660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
4670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              return true;
4680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
4690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              String buildInfo = contentsOfFile(buildInfoFile);
4700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              String buildInfoPlugin = contentsOfFile(buildInfoPlugins);
4710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              if (buildInfo == null || buildInfoPlugin == null
4720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  || buildInfo.compareTo(buildInfoPlugin) != 0) {
47331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                if (LOGV_ENABLED) {
4740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  Log.v(TAG, "build.prop are different, "
4750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + " therefore it's a new system image");
4760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
4770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
4780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
4790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (Exception e) {
4810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exc in newSystemImage(): " + e);
4820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
4830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          return false;
4840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Check if the version of the plugins contained in the
4880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Browser assets is the same as the version of the plugins
4890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * in the plugins directory.
4900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We simply iterate on every file in the assets/plugins
4910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * and return false if a file listed in the assets does
4920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * not exist in the plugins directory.
4930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private boolean checkIsDifferentVersions() {
4950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
4960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ZipFile zip = new ZipFile(APK_PATH);
4970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Vector<ZipEntry> files = pluginsFilesFromZip(zip);
4980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int zipFilterLength = ZIP_FILTER.length();
4990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Enumeration entries = files.elements();
5010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            while (entries.hasMoreElements()) {
5020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              ZipEntry entry = (ZipEntry) entries.nextElement();
5030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              String path = entry.getName().substring(zipFilterLength);
5040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              File outputFile = new File(pluginsPath, path);
5050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              if (!outputFile.exists()) {
50631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                if (LOGV_ENABLED) {
5070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  Log.v(TAG, "checkIsDifferentVersions(): extracted file "
5080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + path + " does not exist, we have a different version");
5090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
5110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
5120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (IOException e) {
5140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exception in checkDifferentVersions(): " + e);
5150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
5160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          return false;
5170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
5200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Copy every files from the assets/plugins directory
5210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * to the app_plugins directory in the data partition.
5220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Once copied, we copy over the SYSTEM_BUILD_INFOS file
5230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * in the plugins directory.
5240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
5250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * NOTE: we directly access the content from the Browser
5260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * package (it's a zip file) and do not use AssetManager
5270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * as there is a limit of 1Mb (see Asset.h)
5280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
5290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void run() {
5300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Lower the priority
5310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
5330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (pluginsPath == null) {
5340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Log.e(TAG, "No plugins path found!");
5350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ZipFile zip = new ZipFile(APK_PATH);
5390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Vector<ZipEntry> files = pluginsFilesFromZip(zip);
5400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Vector<File> plugins = new Vector<File>();
5410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int zipFilterLength = ZIP_FILTER.length();
5420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Enumeration entries = files.elements();
5440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                while (entries.hasMoreElements()) {
5450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ZipEntry entry = (ZipEntry) entries.nextElement();
5460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String path = entry.getName().substring(zipFilterLength);
5470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    File outputFile = new File(pluginsPath, path);
5480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    outputFile.getParentFile().mkdirs();
5490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (outputFile.exists() && !mDoOverwrite) {
55131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
5520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(TAG, path + " already extracted.");
5530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
5540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
5550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (path.endsWith(PLUGIN_EXTENSION)) {
5560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // We rename plugins to be sure a half-copied
5570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // plugin is not loaded by the browser.
5580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            plugins.add(outputFile);
5590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            outputFile = new File(pluginsPath,
5600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                path + TEMPORARY_EXTENSION);
5610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
5620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        FileOutputStream fos = new FileOutputStream(outputFile);
56331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
5640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(TAG, "copy " + entry + " to "
5650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                + pluginsPath + "/" + path);
5660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
5670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        copyStreams(zip.getInputStream(entry), fos);
5680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
5690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // We now rename the .so we copied, once all their resources
5720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // are safely copied over to the user data partition.
5730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Enumeration elems = plugins.elements();
5740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                while (elems.hasMoreElements()) {
5750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    File renamedFile = (File) elems.nextElement();
5760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    File sourceFile = new File(renamedFile.getPath()
5770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + TEMPORARY_EXTENSION);
57831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGV_ENABLED) {
5790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.v(TAG, "rename " + sourceFile.getPath()
5800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " to " + renamedFile.getPath());
5810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
5820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    sourceFile.renameTo(renamedFile);
5830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                copyBuildInfos();
5860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Refresh the plugin list.
5880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentWebView() != null) {
5890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getCurrentWebView().refreshPlugins(false);
5900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IOException e) {
5920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "IO Exception: " + e);
5930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
5960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
5980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Copy the content of assets/plugins/ to the app_plugins directory
5990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * in the data partition.
6000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
6010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called every time the browser is started.
6020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * We first check if the system image is newer than the one that
6030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * copied the plugins (if there's plugins in the data partition).
6040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If this is the case, we then check if the versions are different.
6050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If they are different, we clean the plugins directory in the
6060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * data partition, then start a thread to copy the plugins while
6070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the browser continue to load.
6080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
6090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param overwrite if true overwrite the files even if they are
6100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * already present (to let the user "reset" the plugins if needed).
6110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
6120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copyPlugins(boolean overwrite) {
6130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        CopyPlugins copyPluginsFromAssets = new CopyPlugins(overwrite, this);
6140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        copyPluginsFromAssets.initPluginsPath();
6150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (copyPluginsFromAssets.newSystemImage())  {
6160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (copyPluginsFromAssets.checkIsDifferentVersions()) {
6170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyPluginsFromAssets.cleanPluginsDirectory();
6180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Thread copyplugins = new Thread(copyPluginsFromAssets);
6190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyplugins.setName("CopyPlugins");
6200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyplugins.start();
6210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
6220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
6240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class ClearThumbnails extends AsyncTask<File, Void, Void> {
6260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
6270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
6280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
6290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
6300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    f.delete();
6310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
6320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
6330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
6340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
6360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public void onCreate(Bundle icicle) {
63831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
6390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
6400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
6420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
6430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        this.requestWindowFeature(Window.FEATURE_RIGHT_ICON);
6440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        this.requestWindowFeature(Window.FEATURE_PROGRESS);
6450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
6460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
6480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
6490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
6510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
6530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
6550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // start MASF proxy service
6560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
6570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
6580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
6590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //    (new ComponentName(
6600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
6610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
6620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //startService(proxyServiceIntent, null);
6630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mGenericFavicon = getResources().getDrawable(
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.drawable.app_web_browser_sm);
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView = (FrameLayout) getWindow().getDecorView().findViewById(
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                com.android.internal.R.id.content);
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
6760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
6780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
6790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
6810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
6820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
6830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.loadFromDb(this);
6840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
6860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
6870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
688565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // If this was a web search request, pass it on to the default web search provider.
689565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (handleWebSearchIntent(getIntent())) {
690565505b1a2c1d3099496af5910760087602e994aSatish Sampath            moveTaskToBack(true);
691565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return;
692565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
693565505b1a2c1d3099496af5910760087602e994aSatish Sampath
6940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
6950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
6960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
6970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
6980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
6990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
7000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
70525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
70625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
7070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab t = mTabControl.createNewTab(
7080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent.ACTION_VIEW.equals(intent.getAction()) &&
709f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    intent.getData() != null,
71025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
7110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
7120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This is one of the only places we call attachTabToContentView
7130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // without animating from the tab picker.
7140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
7160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
7170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
7180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
7190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
7200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we are not restoring from an icicle, then there is a high
7230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // likely hood this is the first run. So, check to see if the
7240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // homepage needs to be configured and copy any plugins from our
7250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // asset directory to the data partition.
7260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((extra == null || !extra.getBoolean("testing"))
7270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    && !mSettings.isLoginInitialized()) {
7280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                setupHomePage();
7290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyPlugins(true);
7310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
73225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
7330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mSettings.isLoginInitialized()) {
7340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.loadUrl(mSettings.getHomePage());
7350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    waitForCredentials();
7370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
73981678d9216458266ea70cd62d52f28f744873556Grace Kloba                if (extra != null) {
74081678d9216458266ea70cd62d52f28f744873556Grace Kloba                    urlData.setPostData(extra
74181678d9216458266ea70cd62d52f28f744873556Grace Kloba                            .getByteArray(Browser.EXTRA_POST_DATA));
74281678d9216458266ea70cd62d52f28f744873556Grace Kloba                }
74325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData.loadIn(webView);
7440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
7460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
7470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // restoring the state fails. Attach it to the view here since we
7480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not animating from the tab picker.
7490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
7500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /* enables registration for changes in network status from
7530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project           http stack */
7540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mNetworkStateChangedFilter = new IntentFilter();
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mNetworkStateChangedFilter.addAction(
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ConnectivityManager.CONNECTIVITY_ACTION);
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mNetworkStateIntentReceiver = new BroadcastReceiver() {
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                @Override
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                public void onReceive(Context context, Intent intent) {
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (intent.getAction().equals(
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            ConnectivityManager.CONNECTIVITY_ACTION)) {
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        boolean down = intent.getBooleanExtra(
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        onNetworkToggle(!down);
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            };
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
7710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
7720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
7740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
7760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
7770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
7780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
7850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
7870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
7880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
7890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
7900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
7910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
7920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
7940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
7950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
7960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_WEB_SEARCH.equals(action)) {
797565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
798565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
799565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
800565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
801565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
802565505b1a2c1d3099496af5910760087602e994aSatish Sampath
80325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
80425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
80525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
8060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
80781678d9216458266ea70cd62d52f28f744873556Grace Kloba            urlData.setPostData(intent
80881678d9216458266ea70cd62d52f28f744873556Grace Kloba                    .getByteArrayExtra(Browser.EXTRA_POST_DATA));
80925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
810cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            final String appId = intent
811cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    .getStringExtra(Browser.EXTRA_APPLICATION_ID);
812cc63403643786905262f505ab5266d8e80b9924cGrace Kloba            if (Intent.ACTION_VIEW.equals(action)
813cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && !getPackageName().equals(appId)
814cc63403643786905262f505ab5266d8e80b9924cGrace Kloba                    && (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
815f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                final TabControl.Tab appTab = mTabControl.getTabFromId(appId);
816f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
817f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
818f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
819f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
820f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
821f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
822f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
823f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
824f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
825f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
826f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
82725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            mTabControl.recreateWebView(appTab, urlData.mUrl);
82825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
829f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
83025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                        showTab(appTab, needsLoad ? urlData : EMPTY_URL_DATA);
831f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
832f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        if (mTabOverview != null && mAnimationCount == 0) {
833f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            sendAnimateFromOverview(appTab, false,
83425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                                    needsLoad ? urlData : EMPTY_URL_DATA, TAB_OVERVIEW_DELAY,
835f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                                    null);
836f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        } else {
837f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            // If the tab was the current tab, we have to attach
838f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            // it to the view system again.
839f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            attachTabToContentView(appTab);
840f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            if (needsLoad) {
84125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                                urlData.loadIn(appTab.getWebView());
842f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            }
843f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
844f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
845f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
846f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
8470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url will be
8480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // opened in a new tab unless we have reached MAX_TABS. Then the
8490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // url will be opened in the current tab. If a new tab is
8500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // created, it will have "true" for exit on close.
85125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                openTabAndShow(urlData, null, true, appId);
8520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
85325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("about:debug".equals(urlData.mUrl)) {
8540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSettings.toggleDebugSettings();
8550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
8560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
8570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // If the Window overview is up and we are not in the midst of
8580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // an animation, animate away from the Window overview.
8590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabOverview != null && mAnimationCount == 0) {
86025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    sendAnimateFromOverview(current, false, urlData,
8610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            TAB_OVERVIEW_DELAY, null);
8620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
8630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Get rid of the subwindow if it exists
8640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
86525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    urlData.loadIn(current.getWebView());
8660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
8670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
8700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
871565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
872565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
873565505b1a2c1d3099496af5910760087602e994aSatish Sampath
874565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
875565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
876565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
877565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
878565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
879565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
880565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
881565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
882565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
883565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
884565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
885565505b1a2c1d3099496af5910760087602e994aSatish Sampath
886565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
887565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
888565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
889565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
890565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
891565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
892565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
893565505b1a2c1d3099496af5910760087602e994aSatish Sampath
894565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
895565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
896565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
897565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getData().toString();
898565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
899565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
900565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
901565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
902565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
90315e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA));
904565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
905565505b1a2c1d3099496af5910760087602e994aSatish Sampath
906565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
907565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
908565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
909565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
910565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
91115e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath    private boolean handleWebSearchRequest(String inUrl, Bundle appData) {
912565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
913565505b1a2c1d3099496af5910760087602e994aSatish Sampath
914565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
915565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
916565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
917565505b1a2c1d3099496af5910760087602e994aSatish Sampath
918565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
919565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
920565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Regex.WEB_URL_PATTERN.matcher(url).matches()
921bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
922565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
923565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
924565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
925565505b1a2c1d3099496af5910760087602e994aSatish Sampath
926565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.updateVisitedHistory(mResolver, url, false);
927565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.addSearchUrl(mResolver, url);
928565505b1a2c1d3099496af5910760087602e994aSatish Sampath
929565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
930565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
931565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
93215e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
93315e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
93415e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
935cc63403643786905262f505ab5266d8e80b9924cGrace Kloba        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
936565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
937565505b1a2c1d3099496af5910760087602e994aSatish Sampath
938565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
939565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
940565505b1a2c1d3099496af5910760087602e994aSatish Sampath
94125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
9420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
9430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
9440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
9450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
9460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
9470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
9480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
9490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
9500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
9510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
9520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
9530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
95425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("inline:".equals(url)) {
95525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    return new InlinedUrlData(
95625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_CONTENT),
95725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getType(),
95825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_ENCODING),
95925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_FAILURL));
96025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
9610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
9620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
9630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
9640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
9650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
9660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
9670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Don't add Urls, just search terms.
9680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Urls will get added when the page is loaded.
9690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!Regex.WEB_URL_PATTERN.matcher(url).matches()) {
9700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Browser.updateVisitedHistory(mResolver, url, false);
9710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
9720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
9730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
9740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
9750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
9760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
9770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
9780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
9790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
9800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
9810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = appData.getString(SearchManager.SOURCE);
9820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
9830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
9840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
9850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
9860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
9870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
9880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
9890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
9900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
99125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        return new UrlData(url);
9920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
9940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
9950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
9960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
9970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
9980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
9990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
10000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
10010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
10020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
10040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
10070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Looking for the pattern like this
10080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
10090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *          *
10100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *         * *
10110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *      ***   *     *******
10120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *             *   *
10130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *              * *
10140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *               *
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
10160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final SensorListener mSensorListener = new SensorListener() {
10170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private long mLastGestureTime;
10180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrev = new float[3];
10190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrevDiff = new float[3];
10200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mDiff = new float[3];
10210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mRevertDiff = new float[3];
10220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onSensorChanged(int sensor, float[] values) {
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean show = false;
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            float[] diff = new float[3];
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            for (int i = 0; i < 3; i++) {
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                diff[i] = values[i] - mPrev[i];
10290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Math.abs(diff[i]) > 1) {
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    show = true;
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((diff[i] > 1.0 && mDiff[i] < 0.2)
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        || (diff[i] < -1.0 && mDiff[i] > -0.2)) {
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // start track when there is a big move, or revert
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mRevertDiff[i] = mDiff[i];
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = 0;
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else if (diff[i] > -0.2 && diff[i] < 0.2) {
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // reset when it is flat
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = mRevertDiff[i]  = 0;
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mDiff[i] += diff[i];
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrevDiff[i] = diff[i];
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrev[i] = values[i];
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only shows if we think the delta is big enough, in an attempt
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // to detect "serious" moves left/right or up/down
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "sensorChanged " + sensor + " ("
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + values[0] + ", " + values[1] + ", " + values[2] + ")"
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + " diff(" + diff[0] + " " + diff[1] + " " + diff[2]
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + ")");
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "      mDiff(" + mDiff[0] + " "
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mDiff[1] + " " + mDiff[2] + ")" + " mRevertDiff("
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[0] + " " + mRevertDiff[1] + " "
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[2] + ")");
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            long now = android.os.SystemClock.uptimeMillis();
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (now - mLastGestureTime > 1000) {
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mLastGestureTime = 0;
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float y = mDiff[1];
10640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float z = mDiff[2];
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ay = Math.abs(y);
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float az = Math.abs(z);
10670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ry = mRevertDiff[1];
10680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float rz = mRevertDiff[2];
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ary = Math.abs(ry);
10700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float arz = Math.abs(rz);
10710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestY = ay > 2.5f && ary > 1.0f && ay > ary;
10720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestZ = az > 3.5f && arz > 1.0f && az > arz;
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((gestY || gestZ) && !(gestY && gestZ)) {
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = mTabControl.getCurrentWebView();
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (view != null) {
10780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (gestZ) {
10790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (z < 0) {
10800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomOut();
10810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            } else {
10820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomIn();
10830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
10840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
10850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            view.flingScroll(0, Math.round(y * 100));
10860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
10870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
10880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastGestureTime = now;
10890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
10900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onAccuracyChanged(int sensor, int accuracy) {
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TODO Auto-generated method stub
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onResume() {
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
110131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
11020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resumeWebView();
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null) {
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // In case credential request never comes back
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.doFlick()) {
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSensorManager == null) {
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSensorManager = (SensorManager) getSystemService(
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Context.SENSOR_SERVICE);
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.registerListener(mSensorListener,
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_ACCELEROMETER,
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_DELAY_FASTEST);
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager = null;
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onSaveInstanceState(Bundle outState) {
114831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onPause() {
11620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
11670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebView()) {
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the credentials toast if it is up
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null && mCredsDlg.isShowing()) {
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
11850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
11860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
11870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSensorManager != null) {
11890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.unregisterListener(mSensorListener);
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onDestroy() {
119431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab t = mTabControl.getCurrentTab();
1200e8dc977d91b95b3b3f56ffdadebeba4a04001200Patrick Scott        if (t != null) {
1201e8dc977d91b95b3b3f56ffdadebeba4a04001200Patrick Scott            dismissSubWindow(t);
1202e8dc977d91b95b3b3f56ffdadebeba4a04001200Patrick Scott            removeTabFromContentView(t);
1203e8dc977d91b95b3b3f56ffdadebeba4a04001200Patrick Scott        }
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mGlsConnection != null) {
12080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            unbindService(mGlsConnection);
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mGlsConnection = null;
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // stop MASF proxy service
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //   (new ComponentName(
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //stopService(proxyServiceIntent);
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
12280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
12290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
12300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
12310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoFromShowSSLCertificateOnError.booleanValue());
12320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
12340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
12350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
12360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
12370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
12390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
12400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
12460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
12470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
12480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
12490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
12500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
12510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
12520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
12530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
12540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
12550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
12560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
12570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
12580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mFindDialog != null && mFindDialog.isShowing()) {
12600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mFindDialog.onConfigurationChanged(newConfig);
12610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public void onLowMemory() {
12650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
12660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
12670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean resumeWebView() {
12700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if ((!mActivityInPause && !mPageStarted) ||
12710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (mActivityInPause && mPageStarted)) {
12720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
12730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
12740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
12750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
12760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
12780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
12790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
12800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean pauseWebView() {
12840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause && !mPageStarted) {
12850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
12860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
12870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
12880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
12890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
12910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
12920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
12930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
12970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called when we are launching for the first time. We
12980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * are waiting for the login credentials before loading Google home
12990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * pages. This way the user will be logged in straight away.
13000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
13010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void waitForCredentials() {
13020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show a toast
13030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = new ProgressDialog(this);
13040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setIndeterminate(true);
13050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
13060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the user cancels the operation, then cancel the Google
13070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Credentials request.
13080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
13090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.show();
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // We set a timeout for the retrieval of credentials in onResume()
13120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // as that is when we have freed up some CPU time to get
13130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the login credentials.
13140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
13170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If we have received the credentials or we have timed out and we are
13180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * showing the credentials dialog, then it is time to move on.
13190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
13200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resumeAfterCredentials() {
13210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg == null) {
13220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
13230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the toast
13260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg.isShowing()) {
13270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
13280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
13300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear any pending timeout
13320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
13330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the page
13350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
13360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.loadUrl(mSettings.getHomePage());
13380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Update the settings, need to do this last as it can take a moment
13410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to persist the settings. In the mean time we could be loading
13420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // content.
13430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setLoginInitialized(this);
13440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
13470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
13480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
13490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
13500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
13510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Cursor c = Browser.getAllBookmarks(mResolver);
13520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!c.moveToFirst()) {
13530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.deactivate();
13540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
13550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
13560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
13570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            do {
13580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = c.getString(urlIndex);
13590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                db.retainIconForPageUrl(url);
13600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } while (c.moveToNext());
13610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            c.deactivate();
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
13740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
13750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
13770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
13780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
13790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
13800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
13810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
13840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
13850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
13860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
13870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
13880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
13900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
13910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
13930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
13940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
13950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
13960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
13970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
13980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
14020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
14030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
14040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
14050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
14060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView webView = getTopWindow();
14070d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        if (null == webView) {
14080d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
14090d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
14100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final HashMap hrefMap = new HashMap();
14110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        hrefMap.put("webview", webView);
14120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Message msg = mHandler.obtainMessage(
14130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                FOCUS_NODE_HREF, id, 0, hrefMap);
14140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
14150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
14160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
14170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
14180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
14190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
14200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
14210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
14220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
14230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
14260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
14270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return onOptionsItemSelected(item);
14280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
14300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
14310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
14340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
14350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bundle.putString(SearchManager.SOURCE, source);
14360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
14370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
14404e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project     * Overriding this to insert a local information bundle
14410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onSearchRequested() {
1444cf849950fe8ad5425ccd82b48b9a014dea8a288eGrace Kloba        String url = getTopWindow().getUrl();
144583f473462fcd7869031a423c02b957c6e938a2f6Grace Kloba        startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
14464e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
14470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
14520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
14530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
14540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
14550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
14570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
14650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14660d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        if (null == mTabOverview && null == getTopWindow()) {
14670d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
14680d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
14696ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        if (mMenuIsDown) {
14706ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The shortcut action consumes the MENU. Even if it is still down,
14716ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // it won't trigger the next shortcut action. In the case of the
14726ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // shortcut action triggering a new activity, like Bookmarks, we
14736ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // won't get onKeyUp for MENU. So it is important to reset it here.
14746ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            mMenuIsDown = false;
14756ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        }
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.goto_menu_id: {
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = getTopWindow().getUrl();
14800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_GOTO), false);
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmarks_menu_id:
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(false);
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.windows_menu_id:
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getTabCount() == 1) {
1491f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    openTabAndShow(mSettings.getHomePage(), null, false, null);
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    tabPicker(true, mTabControl.getCurrentIndex(), false);
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
14960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final int currentIndex = mTabControl.getCurrentIndex();
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab parent =
15210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getCurrentTab().getParentTab();
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int indexToShow = -1;
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (parent != null) {
15240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    indexToShow = mTabControl.getTabIndex(parent);
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Get the last tab in the list. If it is the current tab,
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // subtract 1 more.
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    indexToShow = mTabControl.getTabCount() - 1;
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (currentIndex == indexToShow) {
15300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        indexToShow--;
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                switchTabs(currentIndex, indexToShow, true);
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TabControl.Tab current = mTabControl.getCurrentTab();
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current.getWebView().loadUrl(mSettings.getHomePage());
15410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.setWebView(getTopWindow());
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.show();
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
15670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(true);
15680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Browser.sendString(this, getTopWindow().getUrl());
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Tab menu
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_tab_menu_id:
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabOverview.setCurrentIndex(pos);
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabListener.onClick(pos);
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.remove_tab_menu_id:
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabListener.remove(pos);
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.new_tab_menu_id:
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No need to check for mTabOverview here since we are not
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // dependent on it for a position.
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null) {
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // If the overview happens to be non-null, make the "New
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Tab" cell visible.
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabOverview != null) {
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabOverview.setCurrentIndex(ImageGrid.NEW_TAB);
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabListener.onClick(ImageGrid.NEW_TAB);
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_tab_menu_id:
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    TabControl.Tab t = mTabControl.getTab(pos);
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Since we called populatePickerData for all of the
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // tabs, getTitle and getUrl will return appropriate
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // values.
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Browser.saveBookmark(BrowserActivity.this, t.getTitle(),
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            t.getUrl());
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.history_tab_menu_id:
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(true);
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmarks_tab_menu_id:
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(false);
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.properties_tab_menu_id:
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    showPageInfo(mTabControl.getTab(pos), false);
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            TabControl.Tab desiredTab = mTabControl.getTab(id);
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                switchTabs(mTabControl.getCurrentIndex(), id, false);
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onPrepareOptionsMenu(Menu menu)
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    {
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.TAB_MENU:
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.TAB_MENU, true);
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.TAB_MENU, true);
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean newT = mTabControl.getTabCount() < TabControl.MAX_TABS;
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem tab = menu.findItem(R.id.new_tab_menu_id);
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                tab.setVisible(newT);
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                tab.setEnabled(newT);
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.TAB_MENU, false);
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.TAB_MENU, false);
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.TAB_MENU, false);
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.TAB_MENU, false);
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
17240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
17280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
17290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
17300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
17310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
17360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
17370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // If there is only 1 window, the text will be "New window"
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem windows = menu.findItem(R.id.windows_menu_id);
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                windows.setTitleCondensed(mTabControl.getTabCount() > 1 ?
17510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getString(R.string.view_tabs_condensed) :
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getString(R.string.tab_picker_new_tab));
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
17660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
17740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
17750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
17760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
17770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
17820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
17850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
17860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
17870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
17880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
17890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
17910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
17920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
17930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
17940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
17950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
17960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
17970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
17980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
17990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
18000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
18010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
18020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
18030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
18040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
18060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
18080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
18090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
18100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
18110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
18120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
18130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
18140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.setType(Contacts.People.CONTENT_ITEM_TYPE);
18150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
18160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
18170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
18180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
18190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
18220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
18230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
18240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
18250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
18260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
18270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
18280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
18310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
18320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
18330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
18340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
18350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
18360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
18380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
18420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
18430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
18440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
18450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
18460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
18470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
18480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
18490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getTabCount() < TabControl.MAX_TABS);
18500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
18510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
18520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
18530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
18540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
18550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
18560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
18570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
18590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
18600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
18610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
18620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
18640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
18650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
18660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
18670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
18700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
18710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
18760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachTabToContentView(TabControl.Tab t) {
18770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView main = t.getWebView();
18780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the main WebView.
18790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(main, COVER_SCREEN_PARAMS);
18800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the sub window if necessary
18810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        attachSubWindow(t);
18820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
18830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
18840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
18870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachSubWindow(TabControl.Tab t) {
18880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If a sub window exists, attach it to the content view.
18890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView subView = t.getSubWebView();
18900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (subView != null) {
18910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final View container = t.getSubWebViewContainer();
18920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContentView.addView(container, COVER_SCREEN_PARAMS);
18930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            subView.requestFocus();
18940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
18980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void removeTabFromContentView(TabControl.Tab t) {
1899cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project        // Remove the main WebView.
19000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.removeView(t.getWebView());
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the sub window if it exists.
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (t.getSubWebView() != null) {
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContentView.removeView(t.getSubWebViewContainer());
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
19080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
19090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void dismissSubWindow(TabControl.Tab t) {
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView mainView = t.getWebView();
19110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (t.getSubWebView() != null) {
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Remove the container view and request focus on the main WebView.
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContentView.removeView(t.getSubWebViewContainer());
19140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mainView.requestFocus();
19150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Tell the TabControl to dismiss the subwindow. This will destroy
19160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the WebView.
19170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.dismissSubWindow(t);
19180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Send the ANIMTE_FROM_OVERVIEW message after changing the current tab.
19220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void sendAnimateFromOverview(final TabControl.Tab tab,
192325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            final boolean newTab, final UrlData urlData, final int delay,
19240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Message msg) {
19250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Set the current tab.
19260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.setCurrentTab(tab);
19270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the WebView so it will layout.
19280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        attachTabToContentView(tab);
19290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Set the view to invisibile for now.
19300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        tab.getWebView().setVisibility(View.INVISIBLE);
19310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If there is a sub window, make it invisible too.
19320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (tab.getSubWebView() != null) {
19330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tab.getSubWebViewContainer().setVisibility(View.INVISIBLE);
19340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create our fake animating view.
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final AnimatingView view = new AnimatingView(this, tab);
19370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach it to the view system and make in invisible so it will
19380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // layout but not flash white on the screen.
19390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(view, COVER_SCREEN_PARAMS);
19400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        view.setVisibility(View.INVISIBLE);
19410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Send the animate message.
19420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final HashMap map = new HashMap();
19430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        map.put("view", view);
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the url after the AnimatingView has captured the picture. This
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // prevents any bad layout or bad scale from being used during
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // animation.
194725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        if (!urlData.isEmpty()) {
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dismissSubWindow(tab);
194925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            urlData.loadIn(tab.getWebView());
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        map.put("msg", msg);
19520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessageDelayed(mHandler.obtainMessage(
19530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ANIMATE_FROM_OVERVIEW, newTab ? 1 : 0, 0, map), delay);
19540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Increment the count to indicate that we are in an animation.
19550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mAnimationCount++;
19560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the listener so we don't get any more tab changes.
19570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview.setListener(null);
19580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabListener = null;
19590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the menu empty until the animation completes.
19600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = EMPTY_MENU;
19610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // 500ms animation with 800ms delay
196595d601f66135d078c113c58d9aaa6e4a76fd80f2Patrick Scott    private static final int TAB_ANIMATION_DURATION = 200;
196695d601f66135d078c113c58d9aaa6e4a76fd80f2Patrick Scott    private static final int TAB_OVERVIEW_DELAY     = 500;
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called by TabControl when a tab is requesting focus
19690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void showTab(TabControl.Tab t) {
197095d601f66135d078c113c58d9aaa6e4a76fd80f2Patrick Scott        showTab(t, EMPTY_URL_DATA);
1971f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project    }
1972f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project
197325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private void showTab(TabControl.Tab t, UrlData urlData) {
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Disallow focus change during a tab animation.
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount > 0) {
19760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
19770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int delay = 0;
19790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabOverview == null) {
19800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Add a delay so the tab overview can be shown before the second
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // animation begins.
19820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tabPicker(false, mTabControl.getTabIndex(t), false);
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
198525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        sendAnimateFromOverview(t, false, urlData, delay, null);
198625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    }
198725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
198825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // A wrapper function of {@link #openTabAndShow(UrlData, Message, boolean, String)}
198925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
1990a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott    private TabControl.Tab openTabAndShow(String url, final Message msg,
199125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            boolean closeOnExit, String appId) {
1992a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott        return openTabAndShow(new UrlData(url), msg, closeOnExit, appId);
19930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // url isn't null, it will load the given url. If the tab overview is not
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // showing, it will animate to the tab overview, create a new tab and
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // animate away from it. After the animation completes, it will dispatch
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // the given Message. If the tab overview is already showing (i.e. this
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // method is called from TabListener.onClick(), the method will animate
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // away from the tab overview.
2003a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott    private TabControl.Tab openTabAndShow(UrlData urlData, final Message msg,
2004f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            boolean closeOnExit, String appId) {
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final boolean newTab = mTabControl.getTabCount() != TabControl.MAX_TABS;
20060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab currentTab = mTabControl.getCurrentTab();
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (newTab) {
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int delay = 0;
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the tab overview is up and there are animations, just load
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the url.
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mTabOverview != null && mAnimationCount > 0) {
201225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if (!urlData.isEmpty()) {
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // We should not have a msg here since onCreateWindow
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // checks the animation count and every other caller passes
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // null.
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    assert msg == null;
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // just dismiss the subwindow and load the given url.
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(currentTab);
201925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    urlData.loadIn(currentTab.getWebView());
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // show mTabOverview if it is not there.
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabOverview == null) {
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // We have to delay the animation from the tab picker by the
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // length of the tab animation. Add a delay so the tab
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // overview can be shown before the second animation begins.
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    tabPicker(false, ImageGrid.NEW_TAB, false);
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Animate from the Tab overview after any animations have
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // finished.
2032a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                final TabControl.Tab tab = mTabControl.createNewTab(
2033a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                        closeOnExit, appId, urlData.mUrl);
2034a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                sendAnimateFromOverview(tab, true, urlData, delay, msg);
2035a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                return tab;
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
203725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        } else if (!urlData.isEmpty()) {
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We should not have a msg here.
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            assert msg == null;
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mTabOverview != null && mAnimationCount == 0) {
204125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                sendAnimateFromOverview(currentTab, false, urlData,
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        TAB_OVERVIEW_DELAY, null);
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Get rid of the subwindow if it exists
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                dismissSubWindow(currentTab);
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Load the given url.
204725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData.loadIn(currentTab.getWebView());
20480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
20490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2050a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott        return currentTab;
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Animation createTabAnimation(final AnimatingView view,
20540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final View cell, boolean scaleDown) {
20550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final AnimationSet set = new AnimationSet(true);
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final float scaleX = (float) cell.getWidth() / view.getWidth();
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final float scaleY = (float) cell.getHeight() / view.getHeight();
20580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (scaleDown) {
20590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new ScaleAnimation(1.0f, scaleX, 1.0f, scaleY));
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new TranslateAnimation(0, cell.getLeft(), 0,
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    cell.getTop()));
20620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new ScaleAnimation(scaleX, 1.0f, scaleY, 1.0f));
20640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new TranslateAnimation(cell.getLeft(), 0,
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    cell.getTop(), 0));
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        set.setDuration(TAB_ANIMATION_DURATION);
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        set.setInterpolator(new DecelerateInterpolator());
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return set;
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Animate to the tab overview. currentIndex tells us which position to
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // animate to and newIndex is the position that should be selected after
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // the animation completes.
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If remove is true, after the animation stops, a confirmation dialog will
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be displayed to the user.
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void animateToTabOverview(final int newIndex, final boolean remove,
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AnimatingView view) {
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Find the view in the ImageGrid allowing for the "New Tab" cell.
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int position = mTabControl.getTabIndex(view.mTab);
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            position++;
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Offset the tab position with the first visible position to get a
20860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // number between 0 and 3.
20870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        position -= mTabOverview.getFirstVisiblePosition();
20880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Grab the view that we are going to animate to.
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = mTabOverview.getChildAt(position);
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Animation.AnimationListener l =
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new Animation.AnimationListener() {
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationStart(Animation a) {
2095d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                        if (mTabOverview != null) {
2096d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                            mTabOverview.requestFocus();
2097d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                            // Clear the listener so we don't trigger a tab
2098d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                            // selection.
2099d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                            mTabOverview.setListener(null);
2100d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                        }
21010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationRepeat(Animation a) {}
21030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationEnd(Animation a) {
21040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // We are no longer animating so decrement the count.
21050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mAnimationCount--;
21060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // Make the view GONE so that it will not draw between
21070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // now and when the Runnable is handled.
21080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        view.setVisibility(View.GONE);
21090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // Post a runnable since we can't modify the view
21100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // hierarchy during this callback.
21110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.post(new Runnable() {
21120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void run() {
21130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Remove the AnimatingView.
21140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mContentView.removeView(view);
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (mTabOverview != null) {
21160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Make newIndex visible.
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    mTabOverview.setCurrentIndex(newIndex);
21180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Restore the listener.
21190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    mTabOverview.setListener(mTabListener);
21200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Change the menu to TAB_MENU if the
21210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // ImageGrid is interactive.
21220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    if (mTabOverview.isLive()) {
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mMenuState = R.id.TAB_MENU;
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabOverview.requestFocus();
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    }
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
21270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // If a remove was requested, remove the tab.
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (remove) {
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // During a remove, the current tab has
21300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // already changed. Remember the current one
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // here.
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    final TabControl.Tab currentTab =
21330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            mTabControl.getCurrentTab();
21340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Remove the tab at newIndex from
21350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // TabControl and the tab overview.
21360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    final TabControl.Tab tab =
21370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            mTabControl.getTab(newIndex);
21380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    mTabControl.removeTab(tab);
21390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Restore the current tab.
21400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    if (currentTab != tab) {
21410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabControl.setCurrentTab(currentTab);
21420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    }
21430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    if (mTabOverview != null) {
21440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabOverview.remove(newIndex);
21450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        // Make the current tab visible.
21460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabOverview.setCurrentIndex(
21470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                                mTabControl.getCurrentIndex());
21480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    }
21490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
21500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
21510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        });
21520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                };
21540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Do an animation if there is a view to animate to.
21560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (v != null) {
21570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create our animation
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Animation anim = createTabAnimation(view, v, true);
21590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.setAnimationListener(l);
21600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Start animating
21610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            view.startAnimation(anim);
21620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
21630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If something goes wrong and we didn't find a view to animate to,
21640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just do everything here.
21650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l.onAnimationStart(null);
21660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l.onAnimationEnd(null);
21670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Animate from the tab picker. The index supplied is the index to animate
21710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // from.
21720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void animateFromTabOverview(final AnimatingView view,
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final boolean newTab, final Message msg) {
21740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // firstVisible is the first visible tab on the screen.  This helps
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to know which corner of the screen the selected tab is.
21760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int firstVisible = mTabOverview.getFirstVisiblePosition();
21770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // tabPosition is the 0-based index of of the tab being opened
21780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int tabPosition = mTabControl.getTabIndex(view.mTab);
21790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
21800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Add one to make room for the "New Tab" cell.
21810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tabPosition++;
21820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If this is a new tab, animate from the "New Tab" cell.
21840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (newTab) {
21850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tabPosition = 0;
21860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Location corresponds to the four corners of the screen.
21880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // A new tab or 0 is upper left, 0 for an old tab is upper
21890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // right, 1 is lower left, and 2 is lower right
21900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int location = tabPosition - firstVisible;
21910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Find the view at this location.
21930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = mTabOverview.getChildAt(location);
21940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Wait until the animation completes to replace the AnimatingView.
21960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Animation.AnimationListener l =
21970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new Animation.AnimationListener() {
21980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationStart(Animation a) {}
21990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationRepeat(Animation a) {}
22000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationEnd(Animation a) {
22010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.post(new Runnable() {
22020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void run() {
22030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mContentView.removeView(view);
22040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Dismiss the tab overview. If the cell at the
22050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // given location is null, set the fade
22060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // parameter to true.
22070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                dismissTabOverview(v == null);
22080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                TabControl.Tab t =
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabControl.getCurrentTab();
22100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mMenuState = R.id.MAIN_MENU;
22110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Resume regular updates.
22120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                t.getWebView().resumeTimers();
22130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Dispatch the message after the animation
22140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // completes.
22150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (msg != null) {
22160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    msg.sendToTarget();
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
22180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // The animation is done and the tab overview is
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // gone so allow key events and other animations
22200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // to begin.
22210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mAnimationCount--;
22220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Reset all the title bar info.
22230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                resetTitle();
22240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
22250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        });
22260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                };
22280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (v != null) {
22300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Animation anim = createTabAnimation(view, v, false);
22310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Set the listener and start animating
22320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.setAnimationListener(l);
22330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            view.startAnimation(anim);
22340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Make the view VISIBLE during the animation.
22350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            view.setVisibility(View.VISIBLE);
22360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
22370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Go ahead and do all the cleanup.
22380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l.onAnimationEnd(null);
22390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dismiss the tab overview applying a fade if needed.
22430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void dismissTabOverview(final boolean fade) {
22440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fade) {
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f);
22460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.setDuration(500);
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.startNow();
22480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabOverview.startAnimation(anim);
22490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case there was a problem with animating away from the tab
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // overview
22520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current != null) {
22540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current.setVisibility(View.VISIBLE);
22550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "No current WebView in dismissTabOverview");
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the sub window container visible.
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabControl.getCurrentSubWindow() != null) {
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.getCurrentTab().getSubWebViewContainer()
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setVisibility(View.VISIBLE);
22620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.removeView(mTabOverview);
22642ed6edb70dae14691de2109e97fd54feedd84464Patrick Scott        // Clear all the data for tab picker so next time it will be
22652ed6edb70dae14691de2109e97fd54feedd84464Patrick Scott        // recreated.
22662ed6edb70dae14691de2109e97fd54feedd84464Patrick Scott        mTabControl.wipeAllPickerData();
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview.clear();
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview = null;
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabListener = null;
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2272a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott    private TabControl.Tab openTab(String url) {
22730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
2274f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            TabControl.Tab t = mTabControl.createNewTab();
22750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                t.getWebView().loadUrl(url);
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2278a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott            return t;
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
2280a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott            return openTabAndShow(url, null, false, null);
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
22850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
22860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
22900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
22930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
22940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
22980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
22990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
23010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
23020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
23030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
23060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
23110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
23120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
23130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
23140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
23150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
23160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
23170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
23180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
23220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be (for example, if we
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * load a page from history).
23240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitle() {
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetLockIcon();
23270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
23280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
23310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
23320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        revertLockIcon();
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
23410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
23440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
23470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
23480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
23490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
23500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
23520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
23530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebChromeClient.onProgressChanged(current, progress);
23540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
23570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
23580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
23590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
23600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(item.getUrl(), item.getTitle());
23610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
23620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
23630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(null, null);
23640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
23650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
23690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
23700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
23710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
23720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
23730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setUrlTitle(String url, String title) {
23740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
23750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
23760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // While the tab overview is animating or being shown, block changes
23780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to the title.
23790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount == 0 && mTabOverview == null) {
23800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setTitle(buildUrlTitle(url, title));
23810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
23850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Builds and returns the page title, which is some
23860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * combination of the page URL and title.
23870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
23880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
23890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The page title.
23900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
23910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String buildUrlTitle(String url, String title) {
23920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String urlTitle = "";
23930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
23950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String titleUrl = buildTitleUrl(url);
23960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (title != null && 0 < title.length()) {
23980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (titleUrl != null && 0 < titleUrl.length()) {
23990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    urlTitle = titleUrl + ": " + title;
24000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
24010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    urlTitle = title;
24020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
24030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
24040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (titleUrl != null) {
24050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    urlTitle = titleUrl;
24060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
24070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return urlTitle;
24110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
24150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
24160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
24170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
24180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
24190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
24200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static String buildTitleUrl(String url) {
24220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
24230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
24250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
24260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
24270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
24280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
24290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
24300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
24320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
24330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
24350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
24360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
24370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
24380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
24390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
24400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
24410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
24420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
24430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
24440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
24450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
24480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
24510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setFavicon(Bitmap icon) {
24520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // While the tab overview is animating or being shown, block changes to
24530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the favicon.
24540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount > 0 || mTabOverview != null) {
24550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
24560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable[] array = new Drawable[2];
24580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PaintDrawable p = new PaintDrawable(Color.WHITE);
24590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        p.setCornerRadius(3f);
24600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        array[0] = p;
24610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (icon == null) {
24620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            array[1] = mGenericFavicon;
24630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
24640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            array[1] = new BitmapDrawable(icon);
24650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayerDrawable d = new LayerDrawable(array);
24670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        d.setLayerInset(1, 2, 2, 2, 2);
24680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, d);
24690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Saves the current lock-icon state before resetting
24730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the lock icon. If we have an error, we may need to
24740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * roll back to the previous state.
24750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void saveLockIcon() {
24770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPrevLockType = mLockIconType;
24780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reverts the lock-icon state to the last saved state,
24820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * for example, if we had an error, and need to cancel
24830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the load.
24840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void revertLockIcon() {
24860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = mPrevLockType;
24870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
248831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
24890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.revertLockIcon:" +
24900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  " revert lock icon to " + mLockIconType);
24910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(mLockIconType);
24940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void switchTabs(int indexFrom, int indexToShow, boolean remove) {
24970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
24980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Animate to the tab picker, remove the current tab, then
24990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // animate away from the tab picker to the parent WebView.
25000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        tabPicker(false, indexFrom, remove);
25010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Change to the parent tab
25020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab tab = mTabControl.getTab(indexToShow);
25030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (tab != null) {
250495d601f66135d078c113c58d9aaa6e4a76fd80f2Patrick Scott            sendAnimateFromOverview(tab, false, EMPTY_URL_DATA, delay, null);
25050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
25060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Increment this here so that no other animations can happen in
25070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // between the end of the tab picker transition and the beginning
25080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // of openTabAndShow. This has a matching decrement in the handler
25090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // of OPEN_TAB_AND_SHOW.
25100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mAnimationCount++;
25110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Send a message to open a new tab.
25120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(
25130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mHandler.obtainMessage(OPEN_TAB_AND_SHOW,
25140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mSettings.getHomePage()), delay);
25150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void goBackOnePageOrQuit() {
25190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
25200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
25210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
25220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
25230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
25240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
25250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
25260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
25270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
25280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
25290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
25310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
25320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
25330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
25340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
25350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
25360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            TabControl.Tab parent = current.getParentTab();
25370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
25380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                switchTabs(mTabControl.getCurrentIndex(),
25390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getTabIndex(parent), true);
25400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
25410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
25420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
25430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
25440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
25450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // call pauseWebView() now, we won't be able to call it in
25470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // onPause() as the WebView won't be valid.
25480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    pauseWebView();
25490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
25500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
25510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
25530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
25540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
25550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
25560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
25570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
25580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
25590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
25600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public KeyTracker.State onKeyTracker(int keyCode,
25650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                         KeyEvent event,
25660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                         KeyTracker.Stage stage,
25670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                         int duration) {
25680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if onKeyTracker() is called after activity onStop()
25690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // because of accumulated key events,
25700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // we should ignore it as browser is not active any more.
25710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView topWindow = getTopWindow();
25720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (topWindow == null)
25730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return KeyTracker.State.NOT_TRACKING;
25740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_BACK) {
25760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // During animations, block the back key so that other animations
25770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not triggered and so that we don't end up destroying all the
25780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // WebViews before finishing the animation.
25790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAnimationCount > 0) {
25800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return KeyTracker.State.DONE_TRACKING;
25810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (stage == KeyTracker.Stage.LONG_REPEAT) {
25830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(true);
25840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return KeyTracker.State.DONE_TRACKING;
25850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (stage == KeyTracker.Stage.UP) {
25860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // FIXME: Currently, we do not have a notion of the
25870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // history picker for the subwindow, but maybe we
25880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // should?
25890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView subwindow = mTabControl.getCurrentSubWindow();
25900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (subwindow != null) {
25910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (subwindow.canGoBack()) {
25920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        subwindow.goBack();
25930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
25940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dismissSubWindow(mTabControl.getCurrentTab());
25950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
25970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    goBackOnePageOrQuit();
25980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return KeyTracker.State.DONE_TRACKING;
26000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return KeyTracker.State.KEEP_TRACKING;
26020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return KeyTracker.State.NOT_TRACKING;
26040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
26070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_MENU) {
26080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mMenuIsDown = true;
26096ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba        } else if (mMenuIsDown) {
26106ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // The default key mode is DEFAULT_KEYS_SEARCH_LOCAL. As the MENU is
26116ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // still down, we don't want to trigger the search. Pretend to
26126ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            // consume the key and do nothing.
26136ee9c498b8cf648f1507281ed5a1834ba3390907Grace Kloba            return true;
26140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean handled =  mKeyTracker.doKeyDown(keyCode, event);
26160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!handled) {
26170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (keyCode) {
26180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case KeyEvent.KEYCODE_SPACE:
26190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (event.isShiftPressed()) {
26200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getTopWindow().pageUp(false);
26210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
26220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getTopWindow().pageDown(false);
26230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    handled = true;
26250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
26260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                default:
26280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
26290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return handled || super.onKeyDown(keyCode, event);
26320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
26350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_MENU) {
26360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mMenuIsDown = false;
26370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mKeyTracker.doKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
26390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void stopLoading() {
26420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
26430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
26440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
26450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebViewClient.onPageFinished(w, w.getUrl());
26460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
26480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
26490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
26500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
26510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
26540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
26550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
26560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
26570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // called by a non-UI thread to post the message
26610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void postMessage(int what, int arg1, int arg2, Object obj) {
26620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2, obj));
26630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
26660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
26670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
26680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
26700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
26710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CANCEL_CREDS_REQUEST    = 103;
26720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int ANIMATE_FROM_OVERVIEW   = 104;
26730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int ANIMATE_TO_OVERVIEW     = 105;
26740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int OPEN_TAB_AND_SHOW       = 106;
26750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CHECK_MEMORY            = 107;
26760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int RELEASE_WAKELOCK        = 108;
26770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
26790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
26800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
26820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
26830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case ANIMATE_FROM_OVERVIEW:
26840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    final HashMap map = (HashMap) msg.obj;
26850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    animateFromTabOverview((AnimatingView) map.get("view"),
26860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            msg.arg1 == 1, (Message) map.get("msg"));
26870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
26880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case ANIMATE_TO_OVERVIEW:
26900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    animateToTabOverview(msg.arg1, msg.arg2 == 1,
26910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            (AnimatingView) msg.obj);
26920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
26930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case OPEN_TAB_AND_SHOW:
26950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Decrement mAnimationCount before openTabAndShow because
26960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // the method relies on the value being 0 to start the next
26970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // animation.
26980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mAnimationCount--;
2699f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    openTabAndShow((String) msg.obj, null, false, null);
27000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
27030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
27040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
27050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
27060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
27080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
27090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
27100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
27110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
27120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
27140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
27150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
27160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            loadURL(getTopWindow(), url);
27170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
27180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
2719a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                            final TabControl.Tab parent = mTabControl
2720a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                                    .getCurrentTab();
2721a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                            final TabControl.Tab newTab = openTab(url);
2722a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                            if (newTab != parent) {
2723a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                                parent.addChildTab(newTab);
2724a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                            }
27250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
27260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
27270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
27280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
27290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
27300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
27310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
27320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
27330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Browser.sendString(BrowserActivity.this, url);
27340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
27350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
27360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
27370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
27380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
27390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
27400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
27410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
27420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
27460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    loadURL(getTopWindow(), (String) msg.obj);
27470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
27500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
27510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CANCEL_CREDS_REQUEST:
27540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    resumeAfterCredentials();
27550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CHECK_MEMORY:
27580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // reschedule to check memory condition
27590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mHandler.removeMessages(CHECK_MEMORY);
27600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mHandler.sendMessageDelayed(mHandler.obtainMessage
27610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            (CHECK_MEMORY), CHECK_MEMORY_INTERVAL);
27620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    checkMemory();
27630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
27660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
27670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
27680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
27730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
27750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebViewClient implementation.
27760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
27770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
27790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
27800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
27810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
27820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
27830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebViewClient getWebViewClient() {
27850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebViewClient;
27860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateIcon(String url, Bitmap icon) {
27890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (icon != null) {
27900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
27910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url, icon);
27920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setFavicon(icon);
27940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebViewClient mWebViewClient = new WebViewClient() {
27970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
27980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageStarted(WebView view, String url, Bitmap favicon) {
27990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetLockIcon(url);
28000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(url, null);
28010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Call updateIcon instead of setFavicon so the bookmark
28020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // database can be updated.
28030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateIcon(url, favicon);
28040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSettings.isTracing() == true) {
28060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // FIXME: we should save the trace file somewhere other than data.
28070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // I can't use "/tmp" as it competes for system memory.
28080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                File file = getDir("browserTrace", 0);
28090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String baseDir = file.getPath();
28100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!baseDir.endsWith(File.separator)) baseDir += File.separator;
28110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String host;
28120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
28130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebAddress uri = new WebAddress(url);
28140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    host = uri.mHost;
28150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (android.net.ParseException ex) {
28160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    host = "unknown_host";
28170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                host = host.replace('.', '_');
28190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                baseDir = baseDir + host;
28200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                file = new File(baseDir+".data");
28210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (file.exists() == true) {
28220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    file.delete();
28230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                file = new File(baseDir+".key");
28250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (file.exists() == true) {
28260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    file.delete();
28270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = true;
28290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Debug.startMethodTracing(baseDir, 8 * 1024 * 1024);
28300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
28330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
28340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mStart = SystemClock.uptimeMillis();
28350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mProcessStart = Process.getElapsedCpuTime();
28360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
28370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
28380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
28390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mUserStart = sysCpu[0] + sysCpu[1];
28400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSystemStart = sysCpu[2];
28410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIdleStart = sysCpu[3];
28420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
28430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mUiStart = SystemClock.currentThreadTimeMillis();
28450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mPageStarted) {
28480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = true;
28490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // if onResume() has been called, resumeWebView() does nothing.
28500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                resumeWebView();
28510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // reset sync timer to avoid sync starts during loading a page
28540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().resetSync();
28550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mInLoad = true;
28570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateInLoadMenuItems();
28580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mIsNetworkUp) {
28590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ( mAlertDialog == null) {
28600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mAlertDialog = new AlertDialog.Builder(BrowserActivity.this)
28610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.loadSuspendedTitle)
28620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.loadSuspended)
28630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
28640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
28650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (view != null) {
28670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    view.setNetworkAvailable(false);
28680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
28690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // schedule to check memory condition
28720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler.obtainMessage(CHECK_MEMORY),
28730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CHECK_MEMORY_INTERVAL);
28740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
28770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageFinished(WebView view, String url) {
28780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Reset the title and icon in case we stopped a provisional
28790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // load.
28800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(view);
28810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Update the lock icon image only once we are done loading
28830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateLockIconImage(mLockIconType);
28840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
2886cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project            if (false) {
28870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
28880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
28890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String uiInfo = "UI thread used "
28910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.currentThreadTimeMillis() - mUiStart)
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms";
289331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
28940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, uiInfo);
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //The string that gets written to the log
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String performanceString = "It took total "
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.uptimeMillis() - mStart)
28990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms clock time to load the page."
29000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + "\nbrowser process used "
29010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (Process.getElapsedCpuTime() - mProcessStart)
29020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, user processes used "
29030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
29040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, kernel used "
29050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[2] - mSystemStart) * 10
29060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
29070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms and irq took "
29080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
29090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            * 10 + " ms, " + uiInfo;
291031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
29110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
29120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
29130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url != null) {
29140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // strip the url to maintain consistency
29150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String newUrl = new String(url);
29160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (newUrl.startsWith("http://www.")) {
29170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(11);
29180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("http://")) {
29190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(7);
29200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://www.")) {
29210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(12);
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://")) {
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(8);
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
292531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGD_ENABLED) {
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.d(LOGTAG, newUrl + " loaded");
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        /*
29290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (sWhiteList.contains(newUrl)) {
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // The string that gets pushed to the statistcs
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // service
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            performanceString = performanceString
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nWebpage: "
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + newUrl
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nCarrier: "
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + android.os.SystemProperties
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            .get("gsm.sim.operator.alpha");
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (mWebView != null
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext() != null
29400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext().getSystemService(
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Context.CONNECTIVITY_SERVICE) != null) {
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                ConnectivityManager cManager =
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (ConnectivityManager) mWebView
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getContext().getSystemService(
29450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        Context.CONNECTIVITY_SERVICE);
29460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                NetworkInfo nInfo = cManager
29470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getActiveNetworkInfo();
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (nInfo != null) {
29490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString = performanceString
29500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + "\nNetwork Type: "
29510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + nInfo.getType().toString();
29520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
29540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Checkin.logEvent(mResolver,
29550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Checkin.Events.Tag.WEBPAGE_LOAD,
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString);
29570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.w(LOGTAG, "pushed to the statistics service");
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        */
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             }
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mInTrace) {
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = false;
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Debug.stopMethodTracing();
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mPageStarted) {
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = false;
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // pauseWebView() will do nothing and return false if onPause()
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // is not called yet.
29730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (pauseWebView()) {
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.removeMessages(RELEASE_WAKELOCK);
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(CHECK_MEMORY);
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            checkMemory();
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // return true if want to hijack the url to let another app to handle it
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideUrlLoading(WebView view, String url) {
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith(SCHEME_WTAI)) {
29890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/mc;number
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_MC)) {
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent intent = new Intent(Intent.ACTION_VIEW,
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Uri.parse(WebView.SCHEME_TEL +
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            url.substring(SCHEME_WTAI_MC.length())));
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    startActivity(intent);
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/sd;dtmf
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // dtmf=string(dialstring)
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_SD)) {
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // only send when there is active voice connection
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/ap;number;name
30060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // name=string
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_AP)) {
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30149918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // The "about:" schemes are internal to the browser; don't
30159918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // want these to be dispatched to other apps.
30169918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            if (url.startsWith("about:")) {
30179918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
30189918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
30199918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn
30209918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            Intent intent;
30219918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn
30229918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // perform generic parsing of the URI to turn it into an Intent.
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
30249918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
30259918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            } catch (URISyntaxException ex) {
30269918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
30270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30305b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            // check whether the intent can be resolved. If not, we will see
30315b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            // whether we can download it from the Market.
30325b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            if (getPackageManager().resolveActivity(intent, 0) == null) {
30335b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                String packagename = intent.getPackage();
30345b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                if (packagename != null) {
30355b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    intent = new Intent(Intent.ACTION_VIEW, Uri
30365b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                            .parse("market://search?q=pname:" + packagename));
30375b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
30385b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    startActivity(intent);
30395b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    return true;
30405b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                } else {
30415b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    return false;
30425b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                }
30435b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            }
30445b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba
30459918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // sanitize the Intent, ensuring web pages can not bypass browser
30469918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // security (only access to BROWSABLE activities).
30470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.addCategory(Intent.CATEGORY_BROWSABLE);
30489918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            intent.setComponent(null);
30490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
30500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (startActivityIfNeeded(intent, -1)) {
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (ActivityNotFoundException ex) {
30540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // ignore the error. If no application can handle the URL,
30550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // eg about:blank, assume the browser can handle it.
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                openTab(url);
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                closeOptionsMenu();
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Updates the lock icon. This method is called when we discover another
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * resource to be loaded for this page (for example, javascript). While
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we update the icon type, we do not update the lock icon itself until
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we are done loading, it is slightly more secure this way.
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onLoadResource(WebView view, String url) {
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url != null && url.length() > 0) {
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // It is only if the page claims to be secure
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // that we may have to update the lock:
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mLockIconType == LOCK_ICON_SECURE) {
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // If NOT a 'safe' url, change the lock to mixed content!
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url) || URLUtil.isAboutUrl(url))) {
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mLockIconType = LOCK_ICON_MIXED;
308231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(LOGTAG, "BrowserActivity.updateLockIcon:" +
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                  " updated lock icon to " + mLockIconType + " due to " + url);
30850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show the dialog, asking the user if they would like to continue after
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * an excessive number of HTTP redirects.
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onTooManyRedirects(WebView view, final Message cancelMsg,
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final Message continueMsg) {
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameRedirect)
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrame307Post)
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        continueMsg.sendToTarget();
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3116a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        // Container class for the next error dialog that needs to be
3117a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        // displayed.
3118a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        class ErrorDialog {
3119a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            public final int mTitle;
3120a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            public final String mDescription;
3121a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            public final int mError;
3122a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            ErrorDialog(int title, String desc, int error) {
3123a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                mTitle = title;
3124a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                mDescription = desc;
3125a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                mError = error;
3126a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            }
3127a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        };
3128a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott
3129a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        private void processNextError() {
3130a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            if (mQueuedErrors == null) {
3131a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                return;
3132a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            }
3133a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            // The first one is currently displayed so just remove it.
3134a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            mQueuedErrors.removeFirst();
3135a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            if (mQueuedErrors.size() == 0) {
3136a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                mQueuedErrors = null;
3137a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                return;
3138a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            }
3139a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            showError(mQueuedErrors.getFirst());
3140a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        }
3141a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott
3142a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        private DialogInterface.OnDismissListener mDialogListener =
3143a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                new DialogInterface.OnDismissListener() {
3144a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    public void onDismiss(DialogInterface d) {
3145a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                        processNextError();
3146a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    }
3147a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                };
3148a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        private LinkedList<ErrorDialog> mQueuedErrors;
3149a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott
3150a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        private void queueError(int err, String desc) {
3151a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            if (mQueuedErrors == null) {
3152a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                mQueuedErrors = new LinkedList<ErrorDialog>();
3153a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            }
3154a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            for (ErrorDialog d : mQueuedErrors) {
3155a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                if (d.mError == err) {
3156a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    // Already saw a similar error, ignore the new one.
3157a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    return;
3158a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                }
3159a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            }
3160a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            ErrorDialog errDialog = new ErrorDialog(
3161a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    err == EventHandler.FILE_NOT_FOUND_ERROR ?
3162a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    R.string.browserFrameFileErrorLabel :
3163a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    R.string.browserFrameNetworkErrorLabel,
3164a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    desc, err);
3165a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            mQueuedErrors.addLast(errDialog);
3166a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott
3167a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            // Show the dialog now if the queue was empty.
3168a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            if (mQueuedErrors.size() == 1) {
3169a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                showError(errDialog);
3170a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            }
3171a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        }
3172a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott
3173a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        private void showError(ErrorDialog errDialog) {
3174a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            AlertDialog d = new AlertDialog.Builder(BrowserActivity.this)
3175a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    .setTitle(errDialog.mTitle)
3176a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    .setMessage(errDialog.mDescription)
3177a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    .setPositiveButton(R.string.ok, null)
3178a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    .create();
3179a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            d.setOnDismissListener(mDialogListener);
3180a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            d.show();
3181a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott        }
3182a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show a dialog informing the user of the network error reported by
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * WebCore.
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedError(WebView view, int errorCode,
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String description, String failingUrl) {
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (errorCode != EventHandler.ERROR_LOOKUP &&
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.ERROR_CONNECT &&
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.ERROR_BAD_URL &&
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.ERROR_UNSUPPORTED_SCHEME &&
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.FILE_ERROR) {
3195a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                queueError(errorCode, description);
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3197a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott            Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
3198a6555249850bdc364de11e3ad54b571b91b1a2a0Patrick Scott                    + " " + description);
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We need to reset the title after an error.
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndRevertLockIcon();
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Check with the user if it is ok to resend POST data as the page they
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * are trying to navigate to is the result of a POST.
32070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
32080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
32090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onFormResubmission(WebView view, final Message dontResend,
32100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                       final Message resend) {
32110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
32120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameFormResubmitLabel)
32130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrameFormResubmitMessage)
32140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
32150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
32160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        resend.sendToTarget();
32170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
32180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
32190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
32200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
32210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
32220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
32230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
32250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Insert the url into the visited history database.
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param url The url to be inserted.
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param isReload True if this url is being reloaded.
32330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * FIXME: Not sure what to do when reloading the page.
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void doUpdateVisitedHistory(WebView view, String url,
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isReload) {
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.regionMatches(true, 0, "about:", 0, 6)) {
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Browser.updateVisitedHistory(mResolver, url, true);
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebIconDatabase.getInstance().retainIconForPageUrl(url);
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
32460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Displays SSL error(s) dialog to the user.
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedSslError(
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final WebView view, final SslErrorHandler handler, final SslError error) {
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSettings.showSecurityWarnings()) {
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LayoutInflater factory =
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LayoutInflater.from(BrowserActivity.this);
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final View warningsView =
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    factory.inflate(R.layout.ssl_warnings, null);
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LinearLayout placeholder =
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
32590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_UNTRUSTED)) {
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_untrusted);
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_IDMISMATCH)) {
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_mismatch);
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_EXPIRED)) {
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_expired);
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_NOTYETVALID)) {
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_not_yet_valid);
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.security_warning)
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setView(warningsView)
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.ssl_continue,
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.proceed();
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNeutralButton(R.string.view_certificate,
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    showSSLCertificateOnError(view, handler, error);
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.cancel,
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setOnCancelListener(
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnCancelListener() {
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onCancel(DialogInterface dialog) {
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .show();
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed();
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Handles an HTTP authentication request.
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param handler The authentication handler
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param host The host
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param realm The realm
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedHttpAuthRequest(WebView view,
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final HttpAuthHandler handler, final String host, final String realm) {
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String username = null;
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = null;
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean reuseHttpAuthUsernamePassword =
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.useHttpAuthUsernamePassword();
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (reuseHttpAuthUsernamePassword &&
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (mTabControl.getCurrentWebView() != null)) {
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String[] credentials =
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getCurrentWebView()
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .getHttpAuthUsernamePassword(host, realm);
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (credentials != null && credentials.length == 2) {
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    username = credentials[0];
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    password = credentials[1];
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (username != null && password != null) {
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed(username, password);
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showHttpAuthentication(handler, host, realm, null, null, null, 0);
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only check shortcut key when MENU is held
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return getWindow().isShortcutKey(event.getKeyCode(), event);
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (view != mTabControl.getCurrentTopWebView()) {
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (event.isDown()) {
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyDown(event.getKeyCode(), event);
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyUp(event.getKeyCode(), event);
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebChromeClient implementation
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebChromeClient getWebChromeClient() {
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebChromeClient;
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Helper method to create a new tab or sub window.
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private void createWindow(final boolean dialog, final Message msg) {
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog) {
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabControl.createSubWindow();
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab t = mTabControl.getCurrentTab();
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                attachSubWindow(t);
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(t.getSubWebView());
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg.sendToTarget();
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab parent = mTabControl.getCurrentTab();
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // openTabAndShow will dispatch the message after creating the
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // new WebView. This will prevent another request from coming
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // in during the animation.
3409a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                final TabControl.Tab newTab =
3410a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                        openTabAndShow(EMPTY_URL_DATA, msg, false, null);
3411a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                if (newTab != parent) {
3412a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                    parent.addChildTab(newTab);
3413a0b0e2a2cd78ae78ec50eab2e532d0102facc52dPatrick Scott                }
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(mTabControl.getCurrentWebView());
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onCreateWindow(WebView view, final boolean dialog,
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final boolean userGesture, final Message resultMsg) {
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Ignore these requests during tab animations or if the tab
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // overview is showing.
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAnimationCount > 0 || mTabOverview != null) {
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if we can't create any more tabs or sub windows.
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog && mTabControl.getCurrentSubWindow() != null) {
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_subwindows_dialog_title)
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_subwindows_dialog_message)
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (mTabControl.getTabCount() >= TabControl.MAX_TABS) {
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_windows_dialog_title)
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_windows_dialog_message)
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if this was a user gesture.
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (userGesture) {
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // createWindow will call openTabAndShow for new Windows and
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // that will call tabPicker which will increment
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // mAnimationCount.
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                createWindow(dialog, resultMsg);
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Allow the popup and create the appropriate window.
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener allowListener =
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d,
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                int which) {
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // Same comment as above for setting
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // mAnimationCount.
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            createWindow(dialog, resultMsg);
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // Since we incremented mAnimationCount while the
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // dialog was up, we have to decrement it here.
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mAnimationCount--;
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Block the popup by returning a null WebView.
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener blockListener =
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d, int which) {
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            resultMsg.sendToTarget();
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // We are not going to trigger an animation so
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // unblock keys and animation requests.
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mAnimationCount--;
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Build a confirmation dialog to display to the user.
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog d =
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.Builder(BrowserActivity.this)
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.attention)
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setMessage(R.string.popup_window_attempt)
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.allow, allowListener)
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.block, blockListener)
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setCancelable(false)
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .create();
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Show the confirmation dialog.
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d.show();
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We want to increment mAnimationCount here to prevent a
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // potential race condition. If the user allows a pop-up from a
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // site and that pop-up then triggers another pop-up, it is
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // possible to get the BACK key between here and when the dialog
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // appears.
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mAnimationCount++;
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onCloseWindow(WebView window) {
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final int currentIndex = mTabControl.getCurrentIndex();
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab parent =
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getCurrentTab().getParentTab();
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // JavaScript can only close popup window.
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                switchTabs(currentIndex, mTabControl.getTabIndex(parent), true);
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onProgressChanged(WebView view, int newProgress) {
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Block progress updates to the title bar while the tab overview
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // is animating or being displayed.
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAnimationCount == 0 && mTabOverview == null) {
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        newProgress * 100);
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (newProgress == 100) {
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // onProgressChanged() is called for sub-frame too while
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // onPageFinished() is only called for the main frame. sync
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // cookie and cache promptly here.
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CookieSyncManager.getInstance().sync();
3528cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                if (mInLoad) {
3529cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    mInLoad = false;
3530cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    updateInLoadMenuItems();
3531cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
3532cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project            } else {
3533cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // onPageFinished may have already been called but a subframe
3534cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // is still loading and updating the progress. Reset mInLoad
3535cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // and update the menu items.
3536cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                if (!mInLoad) {
3537cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    mInLoad = true;
3538cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    updateInLoadMenuItems();
3539cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedTitle(WebView view, String title) {
3545598c9ccf8641e0e4563bba2fd5613bcb4de766ecPatrick Scott            String url = view.getUrl();
35460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // here, if url is null, we want to reset the title
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(url, title);
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url == null ||
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url.length() >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith("http://www.")) {
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(11);
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (url.startsWith("http://")) {
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(4);
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = "%" + url;
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String [] selArgs = new String[] { url };
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String where = Browser.BookmarkColumns.URL + " LIKE ? AND "
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + Browser.BookmarkColumns.BOOKMARK + " = 0";
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Browser.HISTORY_PROJECTION, where, selArgs, null);
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (c.moveToFirst()) {
356831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGV_ENABLED) {
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.v(LOGTAG, "updating cursor");
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Current implementation of database only has one entry per
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // url.
357355581a656c7b198dbbac63184cd78c61f7535915Leon Scroggins                    ContentValues map = new ContentValues();
357455581a656c7b198dbbac63184cd78c61f7535915Leon Scroggins                    map.put(Browser.BookmarkColumns.TITLE, title);
357555581a656c7b198dbbac63184cd78c61f7535915Leon Scroggins                    mResolver.update(Browser.BOOKMARKS_URI, map,
357655581a656c7b198dbbac63184cd78c61f7535915Leon Scroggins                            "_id = " + c.getInt(0), null);
35770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
35780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.close();
35790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IllegalStateException e) {
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "BrowserActivity onReceived title", e);
35810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (SQLiteException ex) {
35820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "onReceivedTitle() caught SQLiteException: ", ex);
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedIcon(WebView view, Bitmap icon) {
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateIcon(view.getUrl(), icon);
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
36000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        || !contentDisposition.regionMatches(true, 0, "attachment", 0, 10)) {
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
36100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (getPackageManager().resolveActivity(intent,
36120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        PackageManager.MATCH_DEFAULT_ONLY) != null) {
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // someone knows how to handle this mime type with this scheme, don't download.
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    startActivity(intent);
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (ActivityNotFoundException ex) {
361831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, "activity not found for " + mimetype
36200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                + " over " + Uri.parse(url).getScheme(), ex);
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Best behavior is to fall back to a download in this case
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
36240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
36370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // java.net.URI is a lot stricter than KURL so we have to undo
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // KURL's percent-encoding and redo the encoding using java.net.URI.
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        URI uri = null;
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Undo the percent-encoding that KURL may have done.
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String newUrl = new String(URLUtil.decode(url.getBytes()));
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Parse the url into pieces
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebAddress w = new WebAddress(newUrl);
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String frag = null;
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String query = null;
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String path = w.mPath;
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Break the path into path, query, and fragment
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (path.length() > 0) {
36810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Strip the fragment
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int idx = path.lastIndexOf('#');
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    frag = path.substring(idx + 1);
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                idx = path.lastIndexOf('?');
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query = path.substring(idx + 1);
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query, frag);
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
36960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
36970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
36980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
37010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
37020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        values.put(Downloads.URI, uri.toString());
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        values.put(Downloads.COOKIE_DATA, cookies);
37070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        values.put(Downloads.USER_AGENT, userAgent);
37080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        values.put(Downloads.NOTIFICATION_PACKAGE,
37090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
37100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        values.put(Downloads.NOTIFICATION_CLASS,
37110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class.getCanonicalName());
37120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        values.put(Downloads.VISIBILITY, Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
37130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        values.put(Downloads.MIMETYPE, mimetype);
37140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        values.put(Downloads.FILENAME_HINT, filename);
37150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        values.put(Downloads.DESCRIPTION, uri.getHost());
37160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
37170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            values.put(Downloads.TOTAL_BYTES, contentLength);
37180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
37200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
37210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
37220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
37230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
37240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getContentResolver().insert(Downloads.CONTENT_URI, values);
37260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            viewDownloads(contentUri);
37270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
37360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
37370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        saveLockIcon();
37380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = LOCK_ICON_UNSECURE;
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (URLUtil.isHttpsUrl(url)) {
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mLockIconType = LOCK_ICON_SECURE;
374231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                      " reset lock icon to " + mLockIconType);
37450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
37490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon.  This method is called when the icon needs to be
37530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * reset but we do not know whether we are loading a secure or not secure
37540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * page.
37550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon() {
37570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
37580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        saveLockIcon();
37590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = LOCK_ICON_UNSECURE;
37610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
376231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
37630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
37640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                " reset lock icon to " + mLockIconType);
37650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
37680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
37720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
37740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
37750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
37760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
37770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
37780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
37790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the tab overview is animating or being shown, do not update the
37810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // lock icon.
37820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount == 0 && mTabOverview == null) {
37830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, d);
37840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
37890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
37900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
37910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
37920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
37930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
37940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showPageInfo(final TabControl.Tab tab,
37960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
37970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
37980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
37990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
38010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
38030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
38050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
38060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
38090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
38110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
38130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
38140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
38150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
38160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
38210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
38240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
38300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoFromShowSSLCertificateOnError = new Boolean(fromShowSSLCertificateOnError);
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
38340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
38400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
38410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
38420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
38430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
38490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
38560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
38600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
38610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
38820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
38930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
38950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
38960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
38970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificate(final TabControl.Tab tab) {
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
39210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
39280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
39380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
39390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
39400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
39410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
39440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
39450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
39470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
39480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
39490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
39500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
39530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
39550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
39560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
39590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
39600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
39610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
39620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
39630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
39640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificateOnError(
39660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
39670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
39690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
39700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
39710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
39720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
39750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
39770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
39780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
39800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
39810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
39820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
39830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
39840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
39870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
39880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
39890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
39900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
39910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
39940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
39950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
39960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
39970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
39980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
40010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
40020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
40030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
40040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
40050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
40080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
40090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
40100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
40110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
40120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
40130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
40140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
40150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
40160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
40170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
40180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
40190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
40200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
40210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
40220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
40230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
40250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
40260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
40270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
40280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
40290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
40300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
40310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
40320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
40330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
40350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
40360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
40370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
40390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
40400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
40410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
40420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
40430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
40440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
40450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
40460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
40470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
40480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
40490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
40510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
40520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
40530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
40540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
40550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
40590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
40600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
40610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
40620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
40630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
40650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
40660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
40670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
40700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
40720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
40730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
40750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
40760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
40770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
40780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
40790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
40800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
40810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
40820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
40830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
40860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
40870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
40880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
40890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
40900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
40910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
40920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
40930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
40940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
40970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String issuedOn = reformatCertificateDate(
40980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotBefore());
40990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
41000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
41010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
41030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String expiresOn = reformatCertificateDate(
41040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotAfter());
41050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
41060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
41070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
41090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
41120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Re-formats the certificate date (Date.toString()) string to
41130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * a properly localized date string.
41140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
41150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the original certificate date string if fails to localize.
41160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the original string is null, returns an empty string "".
41170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
41180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String reformatCertificateDate(String certificateDate) {
41190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      String reformattedDate = null;
41200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if (certificateDate != null) {
41220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Date date = null;
41230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
41240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = java.text.DateFormat.getInstance().parse(certificateDate);
41250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (ParseException e) {
41260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = null;
41270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
41280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (date != null) {
41300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              reformattedDate =
41310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  DateFormat.getDateFormat(this).format(date);
41320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
41330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
41340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return reformattedDate != null ? reformattedDate :
41360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          (certificateDate != null ? certificateDate : "");
41370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
41400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
41410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
41420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showHttpAuthentication(final HttpAuthHandler handler,
41430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
41440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
41450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
41460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
41470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
41480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
41490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
41500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
41520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
41530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
41560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
41570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
41580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
41590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
41620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
41630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
41640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
41650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
41660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
41670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
41680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
41690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
41700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
41710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
41720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
41730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
41740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
41750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
41760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
41770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
41780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
41790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
41800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
41810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
41820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
41830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
41840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
41850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
41860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
41870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
41880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
41890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
41900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
41910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
41920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
41930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
41940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
41950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
41960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
41970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
41980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
41990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
42000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
42010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
42020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
42030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
42040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
42050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
42060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
42070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
42090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
42120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
42130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
42140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
42150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
42160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
42170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
42210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
42220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
42230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
42240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
42250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
42260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
42270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
42280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
42290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
42300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
42310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
42320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
42330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
42340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
42350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
42390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
42400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
42410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
42420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
42430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
42440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
42450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
42460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
42470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
42480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
42490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
42500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
42510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
42520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
42530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mInLoad && mAlertDialog == null) {
42540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = new AlertDialog.Builder(this)
42550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.loadSuspendedTitle)
42560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.loadSuspended)
42570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
42580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
42590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
42600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
42620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
42630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
42640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
42680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
42690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
42700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
42710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
42720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
42730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
42740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
42750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
42760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        openTab(data);
42770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
42780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final TabControl.Tab currentTab =
42790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
42800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // If the Window overview is up and we are not in the
42810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // middle of an animation, animate away from it to the
42820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // current tab.
42830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (mTabOverview != null && mAnimationCount == 0) {
428425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            sendAnimateFromOverview(currentTab, false, new UrlData(data),
42850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    TAB_OVERVIEW_DELAY, null);
42860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
42870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            dismissSubWindow(currentTab);
42880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (data != null && data.length() != 0) {
42890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                getTopWindow().loadUrl(data);
42900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
42910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
42920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
42930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
42940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
42950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
42960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
42970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        getTopWindow().requestFocus();
42990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
43000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
43020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
43030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * menu to see the download window, or when a download changes state. It
43040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * shows the download window ontop of the current window.
43050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
43060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void viewDownloads(Uri downloadRecord) {
43070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
43080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
43090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
43100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, this.DOWNLOAD_PAGE);
43110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
43130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
43150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Handle results from Tab Switcher mTabOverview tool
43160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
43170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class TabListener implements ImageGrid.Listener {
43180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void remove(int position) {
43190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Note: Remove is not enabled if we have only one tab.
432031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (DEBUG && mTabControl.getTabCount() == 1) {
43210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                throw new AssertionError();
43220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
43230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Remember the current tab.
43250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            TabControl.Tab current = mTabControl.getCurrentTab();
43260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab remove = mTabControl.getTab(position);
43270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.removeTab(remove);
43280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we removed the current tab, use the tab at position - 1 if
43290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // possible.
43300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == remove) {
43310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // If the user removes the last tab, act like the New Tab item
43320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // was clicked on.
43330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getTabCount() == 0) {
4334f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    current = mTabControl.createNewTab();
43350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    sendAnimateFromOverview(current, true,
433625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            new UrlData(mSettings.getHomePage()), TAB_OVERVIEW_DELAY, null);
43370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
43380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    final int index = position > 0 ? (position - 1) : 0;
43390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current = mTabControl.getTab(index);
43400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
43410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
43420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The tab overview could have been dismissed before this method is
43440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // called.
43450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mTabOverview != null) {
43460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Remove the tab and change the index.
43470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabOverview.remove(position);
43480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabOverview.setCurrentIndex(mTabControl.getTabIndex(current));
43490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
43500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Only the current tab ensures its WebView is non-null. This
43520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // implies that we are reloading the freed tab.
43530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
43540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
43550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onClick(int index) {
43560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Change the tab if necessary.
43570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Index equals ImageGrid.CANCEL when pressing back from the tab
43580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // overview.
43590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (index == ImageGrid.CANCEL) {
43600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                index = mTabControl.getCurrentIndex();
43610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // The current index is -1 if the current tab was removed.
43620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (index == -1) {
43630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Take the last tab as a fallback.
43640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    index = mTabControl.getTabCount() - 1;
43650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
43660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
43670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // NEW_TAB means that the "New Tab" cell was clicked on.
43690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (index == ImageGrid.NEW_TAB) {
4370f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                openTabAndShow(mSettings.getHomePage(), null, false, null);
43710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
43720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                sendAnimateFromOverview(mTabControl.getTab(index),
437395d601f66135d078c113c58d9aaa6e4a76fd80f2Patrick Scott                        false, EMPTY_URL_DATA, 0, null);
43740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
43750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
43760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
43770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // A fake View that draws the WebView's picture with a fast zoom filter.
43790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The View is used in case the tab is freed during the animation because
43800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // of low memory.
43810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static class AnimatingView extends View {
43820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private static final int ZOOM_BITS = Paint.FILTER_BITMAP_FLAG |
43830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Paint.DITHER_FLAG | Paint.SUBPIXEL_TEXT_FLAG;
43840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private static final DrawFilter sZoomFilter =
43850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new PaintFlagsDrawFilter(ZOOM_BITS, Paint.LINEAR_TEXT_FLAG);
43860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final Picture mPicture;
43870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final float   mScale;
43880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final int     mScrollX;
43890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final int     mScrollY;
43900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab  mTab;
43910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AnimatingView(Context ctxt, TabControl.Tab t) {
43930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            super(ctxt);
43940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTab = t;
43950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Use the top window in the animation since the tab overview will
43960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // display the top window in each cell.
43970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final WebView w = t.getTopWindow();
43980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPicture = w.capturePicture();
43990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mScale = w.getScale() / w.getWidth();
44000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mScrollX = w.getScrollX();
44010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mScrollY = w.getScrollY();
44020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
44050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        protected void onDraw(Canvas canvas) {
44060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            canvas.save();
44070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            canvas.drawColor(Color.WHITE);
44080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mPicture != null) {
44090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.setDrawFilter(sZoomFilter);
44100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float scale = getWidth() * mScale;
44110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.scale(scale, scale);
44120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.translate(-mScrollX, -mScrollY);
44130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.drawPicture(mPicture);
44140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
44150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            canvas.restore();
44160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
44180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
44200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  Open the tab picker. This function will always use the current tab in
44210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  its animation.
44220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  @param stay boolean stating whether the tab picker is to remain open
44230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *          (in which case it needs a listener and its menu) or not.
44240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  @param index The index of the tab to show as the selection in the tab
44250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *               overview.
44260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  @param remove If true, the tab at index will be removed after the
44270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                animation completes.
44280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
44290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void tabPicker(final boolean stay, final int index,
44300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final boolean remove) {
44310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabOverview != null) {
44320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
44330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int size = mTabControl.getTabCount();
44360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabListener l = null;
44380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (stay) {
44390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l = mTabListener = new TabListener();
44400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview = new ImageGrid(this, stay, l);
44420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        for (int i = 0; i < size; i++) {
44440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab t = mTabControl.getTab(i);
44450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.populatePickerData(t);
44460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabOverview.add(t);
44470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Tell the tab overview to show the current tab, the tab overview will
44500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // handle the "New Tab" case.
44510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int currentIndex = mTabControl.getCurrentIndex();
44520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview.setCurrentIndex(currentIndex);
44530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the tab overview.
44550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(mTabOverview, COVER_SCREEN_PARAMS);
44560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create a fake AnimatingView to animate the WebView's picture.
44580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab current = mTabControl.getCurrentTab();
44590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final AnimatingView v = new AnimatingView(this, current);
44600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(v, COVER_SCREEN_PARAMS);
44610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        removeTabFromContentView(current);
44620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Pause timers to get the animation smoother.
44630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        current.getWebView().pauseTimers();
44640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Send a message so the tab picker has a chance to layout and get
44660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // positions for all the cells.
44670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessage(mHandler.obtainMessage(ANIMATE_TO_OVERVIEW,
44680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                index, remove ? 1 : 0, v));
44690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setting this will indicate that we are animating to the overview. We
44700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // set it here to prevent another request to animate from coming in
44710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // between now and when ANIMATE_TO_OVERVIEW is handled.
44720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mAnimationCount++;
44730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Always change the title bar to the window overview title while
44740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // animating.
44750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, null);
44760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, null);
44770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
44780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Window.PROGRESS_VISIBILITY_OFF);
44790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setTitle(R.string.tab_picker_title);
44800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the menu empty until the animation completes.
44810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = EMPTY_MENU;
44820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
44830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void bookmarksOrHistoryPicker(boolean startWithHistory) {
44850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
44860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
44870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
44880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
44900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
44910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
44920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
44930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
44940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
44950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
44960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
44970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
44980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
44990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
45000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
45030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
45040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
45050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
45070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
45080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("maxTabsOpen",
45090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabControl.getTabCount() >= TabControl.MAX_TABS);
45100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
45110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
45120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
45130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
45150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
45180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void loadURL(WebView view, String url) {
45190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
45200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
45210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
45220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mWebViewClient.shouldOverrideUrlLoading(view, url)) {
45230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                view.loadUrl(url);
45240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void checkMemory() {
45290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
45300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((ActivityManager) getSystemService(ACTIVITY_SERVICE))
45310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .getMemoryInfo(mi);
45320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // FIXME: mi.lowMemory is too aggressive, use (mi.availMem <
45330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // mi.threshold) for now
45340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        if (mi.lowMemory) {
45350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mi.availMem < mi.threshold) {
45360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG, "Browser is freeing memory now because: available="
45370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (mi.availMem / 1024) + "K threshold="
45380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (mi.threshold / 1024) + "K");
45390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.freeMemory();
45400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
45440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
45450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
45460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
45480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get window count
45520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    int getWindowCount(){
45540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if(mTabControl != null){
45550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getTabCount();
45560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
45570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return 0;
45580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
45610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
45620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
45630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
456425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
45650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
45660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
45670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
45690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
45700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
45710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
45720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
45730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
45740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
45750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
45760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
45770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
45780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
45790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
45810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
45820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
45840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
45850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
45860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
45870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
45880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
4589123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
4590123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
4591123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
4592123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
45930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
45950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
4597565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
4598565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
4599565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
4600565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
4601565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
4602565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
4603565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
4604565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
460547fdfdb989ffb79590a39c40792be995de32e521Grace Kloba                    return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
4606565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
4607565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
4608565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
4609565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
4610565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
46110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
4612565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
46130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
46140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
46160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Regex.WEB_URL_PATTERN.matcher(inUrl).matches()) {
46170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
46180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
462247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba        return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
46230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
46240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int LOCK_ICON_UNSECURE = 0;
46260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int LOCK_ICON_SECURE   = 1;
46270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int LOCK_ICON_MIXED    = 2;
46280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mLockIconType = LOCK_ICON_UNSECURE;
46300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mPrevLockType = LOCK_ICON_UNSECURE;
46310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
46330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
46340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
46350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
46360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ImageGrid       mTabOverview;
46370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
46390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
46400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
46410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
46420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
46430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
46440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
46460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
46470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
46480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
46490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
46510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
46520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mPageStarted;
46540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mActivityInPause = true;
46550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
46570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final KeyTracker mKeyTracker = new KeyTracker(this);
46590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As trackball doesn't send repeat down, we have to track it ourselves
46610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mTrackTrackball;
46620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
46640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
46660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
46670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
46680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
46690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
46700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
46710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
46720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
46730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
46740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
46750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
46760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
46780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
46790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
46800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
46810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
46820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
46830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
46850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
46870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
46880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mGenericFavicon;
46890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
46910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
46920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wait for credentials before loading google.com
46940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ProgressDialog mCredsDlg;
46950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
46970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
46980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
46990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
47000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
47010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
47030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
47040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
47050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mPageInfoView;
47060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
47070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
47080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
47090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Boolean mPageInfoFromShowSSLCertificateOnError;
47100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
47120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
47130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
47140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
47150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
47160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
47170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
47190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
47200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
47210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mSSLCertificateView;
47220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
47240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
47250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
47260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
47270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
47290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
47300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT,
47310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT);
473247fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    // Google search
473347fdfdb989ffb79590a39c40792be995de32e521Grace Kloba    final static String QuickSearch_G = "http://www.google.com/m?q=%s";
47340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
47350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
47360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
47370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
47380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
47390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
47400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
47420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
47440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
47450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
47460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
47470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
47480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
47490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
47500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
47510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
47520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
47530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
47550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabListener mTabListener;
47570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
47590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
47610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
47620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
47640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used during animations to prevent other animations from being triggered.
47660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // A count is used since the animation to and from the Window overview can
47670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // overlap. A count of 0 means no animation where a count of > 0 means
47680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // there are animations in progress.
47690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mAnimationCount;
47700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
47720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
47730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
47740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
47750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
47760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
47770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
47790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
47800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
47810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
47830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static int COMBO_PAGE             = 1;
47840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static int DOWNLOAD_PAGE          = 2;
47850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static int PREFERENCES_PAGE       = 3;
47860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // the frenquency of checking whether system memory is low
47880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static int CHECK_MEMORY_INTERVAL = 30000;     // 30 seconds
478925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
479025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
479125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
479225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
479325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
479425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class UrlData {
479525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mUrl;
479660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        byte[] mPostData;
479760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
479825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
479925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
480025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
480160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
480260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        void setPostData(byte[] postData) {
480360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            mPostData = postData;
480460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
480560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
480625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
480725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            return mUrl == null || mUrl.length() == 0;
480825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
480925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
48107944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        public void loadIn(WebView webView) {
481160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            if (mPostData != null) {
481260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                webView.postUrl(mUrl, mPostData);
481360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            } else {
481460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                webView.loadUrl(mUrl);
481560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            }
481625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
481725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
481825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
481925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
482025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A subclass of UrlData class that can display inlined content using
482125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * {@link WebView#loadDataWithBaseURL(String, String, String, String, String)}.
482225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
482325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class InlinedUrlData extends UrlData {
482425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        InlinedUrlData(String inlined, String mimeType, String encoding, String failUrl) {
482525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            super(failUrl);
482625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mInlined = inlined;
482725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mMimeType = mimeType;
482825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mEncoding = encoding;
482925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
483025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mMimeType;
483125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mInlined;
483225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mEncoding;
48337944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        @Override
483425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
483525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            return mInlined == null || mInlined.length() == 0 || super.isEmpty();
483625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
483725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
48387944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        @Override
48397944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        public void loadIn(WebView webView) {
484025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            webView.loadDataWithBaseURL(null, mInlined, mMimeType, mEncoding, mUrl);
484125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
484225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    }
484325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
484425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static final UrlData EMPTY_URL_DATA = new UrlData(null);
48450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
4846