BrowserActivity.java revision 32e14a6deccfa75490b3032bb4ddd5ae90f89de8
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;
21dd4f4297c08803b238af28dddb373a1aea06cc1eRamanan Rajeswaranimport com.google.android.providers.GoogleSettings.Partner;
220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.Activity;
240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.ActivityManager;
250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.AlertDialog;
260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.ProgressDialog;
270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.app.SearchManager;
280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ActivityNotFoundException;
290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.BroadcastReceiver;
300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ComponentName;
310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentResolver;
320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentValues;
330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Context;
340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface;
350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Intent;
360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.IntentFilter;
370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ServiceConnection;
380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface.OnCancelListener;
39b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.content.pm.PackageInfo;
400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.PackageManager;
410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.ResolveInfo;
420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.AssetManager;
430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Configuration;
440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Resources;
450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.Cursor;
460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.sqlite.SQLiteDatabase;
470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.sqlite.SQLiteException;
480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Color;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.DrawFilter;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Paint;
530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.PaintFlagsDrawFilter;
540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.BitmapDrawable;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.LayerDrawable;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.PaintDrawable;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.hardware.SensorListener;
600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.hardware.SensorManager;
618ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Klobaimport android.location.Location;
628ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Klobaimport android.location.LocationManager;
630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.EventHandler;
670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.IBinder;
750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.RemoteException;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.ServiceManager;
800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemProperties;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.preference.PreferenceManager;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Contacts;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
878ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Klobaimport android.provider.Settings;
880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Contacts.Intents.Insert;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.IClipboard;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.util.Regex;
930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
1060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
1070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.AlphaAnimation;
1080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.Animation;
1090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.AnimationSet;
1100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.DecelerateInterpolator;
1110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.ScaleAnimation;
1120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.TranslateAnimation;
1130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
1140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
1150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
1160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
117b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
1180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
1190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
1200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
1210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
1220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
123092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdochimport android.webkit.WebStorage;
1240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebViewClient;
1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
1310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.BufferedOutputStream;
1330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.FileInputStream;
1350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.FileOutputStream;
1360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.IOException;
1370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.InputStream;
1380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URI;
1400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.text.ParseException;
1430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Enumeration;
1450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
14637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scottimport java.util.LinkedList;
1470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Locale;
1480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Vector;
1490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.zip.ZipEntry;
1520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.zip.ZipFile;
1530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
1550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    implements KeyTracker.OnKeyTracker,
1560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View.OnCreateContextMenuListener,
1570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        DownloadListener {
1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
16031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
16131a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
16231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
16331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
16431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
16531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
1660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IGoogleLoginService mGls = null;
1670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ServiceConnection mGlsConnection = null;
1680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SensorManager mSensorManager = null;
1700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17178a98e459323f938e97789a6131beddbebb459ceNicolas Roard    private WebStorage.QuotaUpdater mWebStorageQuotaUpdater = null;
17278a98e459323f938e97789a6131beddbebb459ceNicolas Roard
173565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
174565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
175565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
176565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
177565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
178565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
179565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* Whitelisted webpages
1810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static HashSet<String> sWhiteList;
1820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    static {
1840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList = new HashSet<String>();
1850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("cnn.com/");
1860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("espn.go.com/");
1870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("nytimes.com/");
1880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("engadget.com/");
1890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("yahoo.com/");
1900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("msn.com/");
1910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("amazon.com/");
1920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("consumerist.com/");
1930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("google.com/m/news");
1940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
1950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    */
1960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setupHomePage() {
1980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Runnable getAccount = new Runnable() {
1990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void run() {
2000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Lower priority
2010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
2020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // get the default home page
2030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String homepage = mSettings.getHomePage();
2040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
2060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mGls == null) return;
2070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
208f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                    if (!homepage.startsWith("http://www.google.")) return;
209f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                    if (homepage.indexOf('?') == -1) return;
210f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba
2110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String hostedUser = mGls.getAccount(GoogleLoginServiceConstants.PREFER_HOSTED);
2120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String googleUser = mGls.getAccount(GoogleLoginServiceConstants.REQUIRE_GOOGLE);
2130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // three cases:
2150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser == googleUser
2170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has only a google account
2180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser != googleUser
2200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has a hosted account and a google account
2210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser != null, googleUser == null
2230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has only a hosted account (so far)
2240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // developers might have no accounts at all
2260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (hostedUser == null) return;
2270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (googleUser == null || !hostedUser.equals(googleUser)) {
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
230f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                        homepage = homepage.replace("?", "/a/" + domain + "?");
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (RemoteException ignore) {
2330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Login service died; carry on
2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (RuntimeException ignore) {
2350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Login service died; carry on
2360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } finally {
2370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    finish(homepage);
2380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            private void finish(final String homepage) {
2420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.post(new Runnable() {
2430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void run() {
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mSettings.setHomePage(BrowserActivity.this, homepage);
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        resumeAfterCredentials();
2460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // as this is running in a separate thread,
2480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // BrowserActivity's onDestroy() may have been called,
2490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // which also calls unbindService().
2500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (mGlsConnection != null) {
2510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // we no longer need to keep GLS open
2520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            unbindService(mGlsConnection);
2530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mGlsConnection = null;
2540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
2550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } });
2560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } };
2570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final boolean[] done = { false };
2590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open a connection to the Google Login Service.  The first
2610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // time the connection is established, set up the homepage depending on
2620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the account in a background thread.
2630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mGlsConnection = new ServiceConnection() {
2640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void onServiceConnected(ComponentName className, IBinder service) {
2650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mGls = IGoogleLoginService.Stub.asInterface(service);
2660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (done[0] == false) {
2670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    done[0] = true;
2680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Thread account = new Thread(getAccount);
2690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    account.setName("GLSAccount");
2700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    account.start();
2710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void onServiceDisconnected(ComponentName className) {
2740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mGls = null;
2750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        };
2770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bindService(GoogleLoginServiceConstants.SERVICE_INTENT,
2790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mGlsConnection, Context.BIND_AUTO_CREATE);
2800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
2830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This class is in charge of installing pre-packaged plugins
2840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * from the Browser assets directory to the user's data partition.
2850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Plugins are loaded from the "plugins" directory in the assets;
2860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Anything that is in this directory will be copied over to the
2870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * user data partition in app_plugins.
2880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
2890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class CopyPlugins implements Runnable {
2900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String TAG = "PluginsInstaller";
2910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String ZIP_FILTER = "assets/plugins/";
2920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String APK_PATH = "/system/app/Browser.apk";
2930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String PLUGIN_EXTENSION = ".so";
2940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String TEMPORARY_EXTENSION = "_temp";
2950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String BUILD_INFOS_FILE = "build.prop";
2960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String SYSTEM_BUILD_INFOS_FILE = "/system/"
2970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              + BUILD_INFOS_FILE;
2980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int BUFSIZE = 4096;
2990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean mDoOverwrite = false;
3000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String pluginsPath;
3010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Context mContext;
3020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        File pluginsDir;
3030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AssetManager manager;
3040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public CopyPlugins (boolean overwrite, Context context) {
3060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mDoOverwrite = overwrite;
3070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContext = context;
3080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Returned a filtered list of ZipEntry.
3120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We list all the files contained in the zip and
3130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * only returns the ones starting with the ZIP_FILTER
3140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * path.
3150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
3160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param zip the zip file used.
3170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Vector<ZipEntry> pluginsFilesFromZip(ZipFile zip) {
3190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Vector<ZipEntry> list = new Vector<ZipEntry>();
3200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Enumeration entries = zip.entries();
3210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            while (entries.hasMoreElements()) {
3220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ZipEntry entry = (ZipEntry) entries.nextElement();
3230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (entry.getName().startsWith(ZIP_FILTER)) {
3240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  list.add(entry);
3250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return list;
3280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Utility method to copy the content from an inputstream
3320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * to a file output stream.
3330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void copyStreams(InputStream is, FileOutputStream fos) {
3350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BufferedOutputStream os = null;
3360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
3370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                byte data[] = new byte[BUFSIZE];
3380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int count;
3390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                os = new BufferedOutputStream(fos, BUFSIZE);
3400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                while ((count = is.read(data, 0, BUFSIZE)) != -1) {
3410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    os.write(data, 0, count);
3420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                os.flush();
3440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IOException e) {
3450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "Exception while copying: " + e);
3460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } finally {
3470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              try {
3480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (os != null) {
3490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    os.close();
3500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              } catch (IOException e2) {
3520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "Exception while closing the stream: " + e2);
3530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
3540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Returns a string containing the contents of a file
3590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
3600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param file the target file
3610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String contentsOfFile(File file) {
3630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          String ret = null;
3640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          FileInputStream is = null;
3650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
3660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            byte[] buffer = new byte[BUFSIZE];
3670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int count;
3680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            is = new FileInputStream(file);
3690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            StringBuffer out = new StringBuffer();
3700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            while ((count = is.read(buffer, 0, BUFSIZE)) != -1) {
3720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              out.append(new String(buffer, 0, count));
3730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ret = out.toString();
3750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (IOException e) {
3760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exception getting contents of file " + e);
3770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } finally {
3780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (is != null) {
3790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              try {
3800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                is.close();
3810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              } catch (IOException e2) {
3820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "Exception while closing the file: " + e2);
3830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
3840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
3860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          return ret;
3870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Utility method to initialize the user data plugins path.
3910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void initPluginsPath() {
3930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BrowserSettings s = BrowserSettings.getInstance();
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            pluginsPath = s.getPluginsPath();
3950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (pluginsPath == null) {
3960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                s.loadFromDb(mContext);
3970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                pluginsPath = s.getPluginsPath();
3980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
4000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(TAG, "Plugin path: " + pluginsPath);
4010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Utility method to delete a file or a directory
4060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
4070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param file the File to delete
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void deleteFile(File file) {
4100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File[] files = file.listFiles();
4110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((files != null) && files.length > 0) {
4120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              for (int i=0; i< files.length; i++) {
4130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                deleteFile(files[i]);
4140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
4150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!file.delete()) {
4170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              Log.e(TAG, file.getPath() + " could not get deleted");
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Clean the content of the plugins directory.
4230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We delete the directory, then recreate it.
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void cleanPluginsDirectory() {
42631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort          if (LOGV_ENABLED) {
4270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(TAG, "delete plugins directory: " + pluginsPath);
4280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
4290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          File pluginsDirectory = new File(pluginsPath);
4300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          deleteFile(pluginsDirectory);
4310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          pluginsDirectory.mkdir();
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Copy the SYSTEM_BUILD_INFOS_FILE file containing the
4370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * informations about the system build to the
4380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * BUILD_INFOS_FILE in the plugins directory.
4390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void copyBuildInfos() {
4410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
44231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
4430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              Log.v(TAG, "Copy build infos to the plugins directory");
4440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
4460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE);
4470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyStreams(new FileInputStream(buildInfoFile),
4480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new FileOutputStream(buildInfoPlugins));
4490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (IOException e) {
4500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exception while copying the build infos: " + e);
4510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Returns true if the current system is newer than the
4560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * system that installed the plugins.
4570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We determinate this by checking the build number of the system.
4580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
4590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * At the end of the plugins copy operation, we copy the
4600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * SYSTEM_BUILD_INFOS_FILE to the BUILD_INFOS_FILE.
4610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We then just have to load both and compare them -- if they
4620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * are different the current system is newer.
4630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
4640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Loading and comparing the strings should be faster than
4650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * creating a hash, the files being rather small. Extracting the
4660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * version number would require some parsing which may be more
4670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * brittle.
4680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean newSystemImage() {
4700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
4710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
4720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE);
4730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!buildInfoPlugins.exists()) {
47431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort              if (LOGV_ENABLED) {
4750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(TAG, "build.prop in plugins directory " + pluginsPath
4760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  + " does not exist, therefore it's a new system image");
4770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
4780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              return true;
4790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
4800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              String buildInfo = contentsOfFile(buildInfoFile);
4810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              String buildInfoPlugin = contentsOfFile(buildInfoPlugins);
4820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              if (buildInfo == null || buildInfoPlugin == null
4830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  || buildInfo.compareTo(buildInfoPlugin) != 0) {
48431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                if (LOGV_ENABLED) {
4850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  Log.v(TAG, "build.prop are different, "
4860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + " therefore it's a new system image");
4870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
4880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
4890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
4900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (Exception e) {
4920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exc in newSystemImage(): " + e);
4930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
4940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          return false;
4950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Check if the version of the plugins contained in the
4990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Browser assets is the same as the version of the plugins
5000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * in the plugins directory.
5010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We simply iterate on every file in the assets/plugins
5020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * and return false if a file listed in the assets does
5030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * not exist in the plugins directory.
5040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
5050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private boolean checkIsDifferentVersions() {
5060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
5070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ZipFile zip = new ZipFile(APK_PATH);
5080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Vector<ZipEntry> files = pluginsFilesFromZip(zip);
5090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int zipFilterLength = ZIP_FILTER.length();
5100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Enumeration entries = files.elements();
5120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            while (entries.hasMoreElements()) {
5130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              ZipEntry entry = (ZipEntry) entries.nextElement();
5140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              String path = entry.getName().substring(zipFilterLength);
5150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              File outputFile = new File(pluginsPath, path);
5160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              if (!outputFile.exists()) {
51731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                if (LOGV_ENABLED) {
5180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  Log.v(TAG, "checkIsDifferentVersions(): extracted file "
5190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + path + " does not exist, we have a different version");
5200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
5220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
5230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (IOException e) {
5250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exception in checkDifferentVersions(): " + e);
5260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
5270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          return false;
5280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
5310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Copy every files from the assets/plugins directory
5320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * to the app_plugins directory in the data partition.
5330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Once copied, we copy over the SYSTEM_BUILD_INFOS file
5340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * in the plugins directory.
5350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
5360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * NOTE: we directly access the content from the Browser
5370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * package (it's a zip file) and do not use AssetManager
5380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * as there is a limit of 1Mb (see Asset.h)
5390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
5400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void run() {
5410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Lower the priority
5420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
5440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (pluginsPath == null) {
5450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Log.e(TAG, "No plugins path found!");
5460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ZipFile zip = new ZipFile(APK_PATH);
5500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Vector<ZipEntry> files = pluginsFilesFromZip(zip);
5510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Vector<File> plugins = new Vector<File>();
5520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int zipFilterLength = ZIP_FILTER.length();
5530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Enumeration entries = files.elements();
5550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                while (entries.hasMoreElements()) {
5560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ZipEntry entry = (ZipEntry) entries.nextElement();
5570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String path = entry.getName().substring(zipFilterLength);
5580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    File outputFile = new File(pluginsPath, path);
5590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    outputFile.getParentFile().mkdirs();
5600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (outputFile.exists() && !mDoOverwrite) {
56231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
5630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(TAG, path + " already extracted.");
5640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
5650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
5660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (path.endsWith(PLUGIN_EXTENSION)) {
5670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // We rename plugins to be sure a half-copied
5680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // plugin is not loaded by the browser.
5690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            plugins.add(outputFile);
5700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            outputFile = new File(pluginsPath,
5710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                path + TEMPORARY_EXTENSION);
5720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
5730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        FileOutputStream fos = new FileOutputStream(outputFile);
57431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
5750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(TAG, "copy " + entry + " to "
5760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                + pluginsPath + "/" + path);
5770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
5780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        copyStreams(zip.getInputStream(entry), fos);
5790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
5800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // We now rename the .so we copied, once all their resources
5830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // are safely copied over to the user data partition.
5840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Enumeration elems = plugins.elements();
5850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                while (elems.hasMoreElements()) {
5860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    File renamedFile = (File) elems.nextElement();
5870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    File sourceFile = new File(renamedFile.getPath()
5880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + TEMPORARY_EXTENSION);
58931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGV_ENABLED) {
5900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.v(TAG, "rename " + sourceFile.getPath()
5910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " to " + renamedFile.getPath());
5920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
5930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    sourceFile.renameTo(renamedFile);
5940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                copyBuildInfos();
5970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IOException e) {
5980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "IO Exception: " + e);
5990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
6000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
6020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
6040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Copy the content of assets/plugins/ to the app_plugins directory
6050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * in the data partition.
6060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
6070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called every time the browser is started.
6080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * We first check if the system image is newer than the one that
6090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * copied the plugins (if there's plugins in the data partition).
6100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If this is the case, we then check if the versions are different.
6110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If they are different, we clean the plugins directory in the
6120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * data partition, then start a thread to copy the plugins while
6130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the browser continue to load.
6140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
6150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param overwrite if true overwrite the files even if they are
6160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * already present (to let the user "reset" the plugins if needed).
6170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
6180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copyPlugins(boolean overwrite) {
6190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        CopyPlugins copyPluginsFromAssets = new CopyPlugins(overwrite, this);
6200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        copyPluginsFromAssets.initPluginsPath();
6210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (copyPluginsFromAssets.newSystemImage())  {
6220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (copyPluginsFromAssets.checkIsDifferentVersions()) {
6230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyPluginsFromAssets.cleanPluginsDirectory();
6240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Thread copyplugins = new Thread(copyPluginsFromAssets);
6250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyplugins.setName("CopyPlugins");
6260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyplugins.start();
6270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
6280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
6300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class ClearThumbnails extends AsyncTask<File, Void, Void> {
6320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
6330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
6340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
6350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
6360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    f.delete();
6370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
6380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
6390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
6400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
6420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
64381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins    // Flag to enable the touchable browser bar with buttons
64481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins    private final boolean CUSTOM_BROWSER_BAR = true;
64581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
6460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public void onCreate(Bundle icicle) {
64731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
6480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
6490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
65181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        if (CUSTOM_BROWSER_BAR) {
65281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
65381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        } else {
65481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
65581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_RIGHT_ICON);
65681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_PROGRESS);
65781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
65881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        }
6590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
6600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
6610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
6630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setBaseSearchUrl(PreferenceManager.getDefaultSharedPreferences(this)
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .getString("search_url", ""));
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // start MASF proxy service
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //    (new ComponentName(
6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
6760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
6770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //startService(proxyServiceIntent, null);
6780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
6800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
6810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
6820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
6830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mGenericFavicon = getResources().getDrawable(
6840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.drawable.app_web_browser_sm);
6850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
68681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
68781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
68881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        if (CUSTOM_BROWSER_BAR) {
68981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            // This LinearLayout will hold the title bar and a FrameLayout, which
69081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            // holds everything else.
691e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins            LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(this)
692e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins                    .inflate(R.layout.custom_screen, null);
693e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins            mTitleBar = (TitleBar) linearLayout.findViewById(R.id.title_bar);
694e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins            mTitleBar.setBrowserActivity(this);
695e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins            mContentView = (FrameLayout) linearLayout.findViewById(
696e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins                    R.id.main_content);
69781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            frameLayout.addView(linearLayout, COVER_SCREEN_PARAMS);
69881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        } else {
69981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            mContentView = frameLayout;
70081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        }
7010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
7030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
7040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
7060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
7070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
7090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
7100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
7110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.loadFromDb(this);
7120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
7140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
716565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // If this was a web search request, pass it on to the default web search provider.
717565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (handleWebSearchIntent(getIntent())) {
718565505b1a2c1d3099496af5910760087602e994aSatish Sampath            moveTaskToBack(true);
719565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return;
720565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
721565505b1a2c1d3099496af5910760087602e994aSatish Sampath
7220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
7230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
7240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
7250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
7260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
7270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
7280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
7290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
7300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
7310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
7320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
73325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
73425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
7350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab t = mTabControl.createNewTab(
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent.ACTION_VIEW.equals(intent.getAction()) &&
737f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    intent.getData() != null,
73825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
7390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
7400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This is one of the only places we call attachTabToContentView
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // without animating from the tab picker.
7420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
7430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
7440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
7450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
7460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
7470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
7480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we are not restoring from an icicle, then there is a high
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // likely hood this is the first run. So, check to see if the
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // homepage needs to be configured and copy any plugins from our
7530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // asset directory to the data partition.
7540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((extra == null || !extra.getBoolean("testing"))
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    && !mSettings.isLoginInitialized()) {
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                setupHomePage();
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyPlugins(true);
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
76025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mSettings.isLoginInitialized()) {
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.loadUrl(mSettings.getHomePage());
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    waitForCredentials();
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
7678ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                byte[] postData = getLocationData(intent);
7688ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                if (postData != null) {
769f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                    webView.postUrl(urlData.mUrl, postData);
7708ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                } else {
771f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                    urlData.loadIn(webView);
7728ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                }
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
7760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // restoring the state fails. Attach it to the view here since we
7770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not animating from the tab picker.
7780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /* enables registration for changes in network status from
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project           http stack */
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mNetworkStateChangedFilter = new IntentFilter();
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mNetworkStateChangedFilter.addAction(
7850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ConnectivityManager.CONNECTIVITY_ACTION);
7860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mNetworkStateIntentReceiver = new BroadcastReceiver() {
7870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                @Override
7880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                public void onReceive(Context context, Intent intent) {
7890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (intent.getAction().equals(
7900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            ConnectivityManager.CONNECTIVITY_ACTION)) {
7910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        boolean down = intent.getBooleanExtra(
7920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
7930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        onNetworkToggle(!down);
7940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
7950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            };
797b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
798b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
799b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
800b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        filter.addDataScheme("package");
801b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
802b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba            @Override
803b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba            public void onReceive(Context context, Intent intent) {
804b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                final String action = intent.getAction();
805b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                final String packageName = intent.getData()
806b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        .getSchemeSpecificPart();
807b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                final boolean replacing = intent.getBooleanExtra(
808b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        Intent.EXTRA_REPLACING, false);
809b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
810b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    // if it is replacing, refreshPlugins() when adding
811b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    return;
812b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                }
813b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
814b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                PackageInfo pkgInfo = null;
815b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                try {
816b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
817b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                            PackageManager.GET_PERMISSIONS);
818b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
819b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    return;
820b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                }
821b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                if (pkgInfo != null) {
822b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
823b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    if (permissions == null) {
824b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        return;
825b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    }
826b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    boolean permissionOk = false;
827b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    for (String permit : permissions) {
828b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
829b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                            permissionOk = true;
830b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                            break;
831b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        }
832b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    }
833b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    if (permissionOk) {
834b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
835b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                                .refreshPlugins(
836b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
837b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                                                .equals(action));
838b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    }
839b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                }
840b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba            }
841b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        };
842b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
8430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
8440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
8460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
8470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
8480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
8490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
8500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
8510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
8520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
8530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
8540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
8550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
8560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
8580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
8590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
8600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
8620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
8630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
8640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
8650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
8660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
8670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
8690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
8700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
8710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_WEB_SEARCH.equals(action)) {
872565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
873565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
874565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
875565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
876565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
877565505b1a2c1d3099496af5910760087602e994aSatish Sampath
87825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
87925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
88025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
8810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
88225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
8830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action) &&
8840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
885f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                final String appId =
886f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        intent.getStringExtra(Browser.EXTRA_APPLICATION_ID);
887f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                final TabControl.Tab appTab = mTabControl.getTabFromId(appId);
888f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
889f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
890f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
891f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
892f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
893f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
894f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
895f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
896f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
897f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
898f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
89925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            mTabControl.recreateWebView(appTab, urlData.mUrl);
90025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
901f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
90225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                        showTab(appTab, needsLoad ? urlData : EMPTY_URL_DATA);
903f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
904f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        if (mTabOverview != null && mAnimationCount == 0) {
905f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            sendAnimateFromOverview(appTab, false,
906f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                                    needsLoad ? urlData : EMPTY_URL_DATA, null,
9078ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                                    TAB_OVERVIEW_DELAY, null);
908f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        } else {
909f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            // If the tab was the current tab, we have to attach
910f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            // it to the view system again.
911f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            attachTabToContentView(appTab);
912f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            if (needsLoad) {
91325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                                urlData.loadIn(appTab.getWebView());
914f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            }
915f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
916f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
917f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
918f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
9190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url will be
9200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // opened in a new tab unless we have reached MAX_TABS. Then the
9210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // url will be opened in the current tab. If a new tab is
9220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // created, it will have "true" for exit on close.
92325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                openTabAndShow(urlData, null, true, appId);
9240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
92525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("about:debug".equals(urlData.mUrl)) {
9260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSettings.toggleDebugSettings();
9270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
9280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
9298ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                byte[] postData = getLocationData(intent);
9300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // If the Window overview is up and we are not in the midst of
9310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // an animation, animate away from the Window overview.
9320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabOverview != null && mAnimationCount == 0) {
93325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    sendAnimateFromOverview(current, false, urlData,
9348ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                            postData, TAB_OVERVIEW_DELAY, null);
9350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
9360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Get rid of the subwindow if it exists
9370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
9388ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    if (postData != null) {
939f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                        current.getWebView().postUrl(urlData.mUrl, postData);
9408ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    } else {
941f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                        urlData.loadIn(current.getWebView());
9428ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    }
9430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
9440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
9450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
948565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
949565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
950565505b1a2c1d3099496af5910760087602e994aSatish Sampath
951565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
952565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
953565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
954565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
955565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
956565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
957565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
958565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
959565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
960565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
961565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
962565505b1a2c1d3099496af5910760087602e994aSatish Sampath
963565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
964565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
965565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
966565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
967565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
968565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
969565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
970565505b1a2c1d3099496af5910760087602e994aSatish Sampath
971565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
972565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
973565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
974565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getData().toString();
975565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
976565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
977565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
978565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
979565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
980565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return handleWebSearchRequest(url);
981565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
982565505b1a2c1d3099496af5910760087602e994aSatish Sampath
983565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
984565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
985565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
986565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
987565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
988565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchRequest(String inUrl) {
989565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
990565505b1a2c1d3099496af5910760087602e994aSatish Sampath
991565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
992565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
993565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
994565505b1a2c1d3099496af5910760087602e994aSatish Sampath
995565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
996565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
997565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Regex.WEB_URL_PATTERN.matcher(url).matches()
998bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
999565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
1000565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
1001565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
1002565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1003565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.updateVisitedHistory(mResolver, url, false);
1004565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.addSearchUrl(mResolver, url);
1005565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1006565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
1007565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
1008565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
1009565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
1010565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1011565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
1012565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
1013565505b1a2c1d3099496af5910760087602e994aSatish Sampath
101425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
10150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
10160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
10170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
10180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
10190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
10200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
10210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
10220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
10230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
10240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
102725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("inline:".equals(url)) {
102825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    return new InlinedUrlData(
102925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_CONTENT),
103025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getType(),
103125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_ENCODING),
103225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_FAILURL));
103325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
10370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
10380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
10390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
10400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Don't add Urls, just search terms.
10410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Urls will get added when the page is loaded.
10420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!Regex.WEB_URL_PATTERN.matcher(url).matches()) {
10430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Browser.updateVisitedHistory(mResolver, url, false);
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = appData.getString(SearchManager.SOURCE);
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
106425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        return new UrlData(url);
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10678ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba    byte[] getLocationData(Intent intent) {
10688ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba        byte[] postData = null;
10698ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba        if (intent != null) {
10708ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            final String action = intent.getAction();
10718ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            if ((Intent.ACTION_SEARCH.equals(action)
10728ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    || Intent.ACTION_WEB_SEARCH.equals(action))
10738ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    && Settings.Secure.isLocationProviderEnabled(
10748ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                            getContentResolver(),
10758ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                            LocationManager.NETWORK_PROVIDER)) {
10768ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                // Attempt to get location info
10778ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                LocationManager locationManager = (LocationManager)
10788ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                        getSystemService(Context.LOCATION_SERVICE);
10798ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                Location location = locationManager
10808ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
10818ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                if (location != null) {
10828ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    StringBuilder str = new StringBuilder("sll=");
10838ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    str.append(location.getLatitude()).append(",").append(
10848ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                            location.getLongitude());
10858ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    postData = str.toString().getBytes();
10868ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                }
10878ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            }
10888ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba        }
10898ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba        return postData;
10908ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba    }
10918ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba
10920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
10930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
10940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
10950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
10960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
10970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
10980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
10990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
11000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
11020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
11050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Looking for the pattern like this
11060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
11070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *          *
11080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *         * *
11090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *      ***   *     *******
11100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *             *   *
11110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *              * *
11120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *               *
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final SensorListener mSensorListener = new SensorListener() {
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private long mLastGestureTime;
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrev = new float[3];
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrevDiff = new float[3];
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mDiff = new float[3];
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mRevertDiff = new float[3];
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onSensorChanged(int sensor, float[] values) {
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean show = false;
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            float[] diff = new float[3];
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            for (int i = 0; i < 3; i++) {
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                diff[i] = values[i] - mPrev[i];
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Math.abs(diff[i]) > 1) {
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    show = true;
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((diff[i] > 1.0 && mDiff[i] < 0.2)
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        || (diff[i] < -1.0 && mDiff[i] > -0.2)) {
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // start track when there is a big move, or revert
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mRevertDiff[i] = mDiff[i];
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = 0;
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else if (diff[i] > -0.2 && diff[i] < 0.2) {
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // reset when it is flat
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = mRevertDiff[i]  = 0;
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mDiff[i] += diff[i];
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrevDiff[i] = diff[i];
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrev[i] = values[i];
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only shows if we think the delta is big enough, in an attempt
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // to detect "serious" moves left/right or up/down
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "sensorChanged " + sensor + " ("
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + values[0] + ", " + values[1] + ", " + values[2] + ")"
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + " diff(" + diff[0] + " " + diff[1] + " " + diff[2]
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + ")");
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "      mDiff(" + mDiff[0] + " "
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mDiff[1] + " " + mDiff[2] + ")" + " mRevertDiff("
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[0] + " " + mRevertDiff[1] + " "
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[2] + ")");
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            long now = android.os.SystemClock.uptimeMillis();
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (now - mLastGestureTime > 1000) {
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mLastGestureTime = 0;
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float y = mDiff[1];
11620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float z = mDiff[2];
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ay = Math.abs(y);
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float az = Math.abs(z);
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ry = mRevertDiff[1];
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float rz = mRevertDiff[2];
11670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ary = Math.abs(ry);
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float arz = Math.abs(rz);
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestY = ay > 2.5f && ary > 1.0f && ay > ary;
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestZ = az > 3.5f && arz > 1.0f && az > arz;
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((gestY || gestZ) && !(gestY && gestZ)) {
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = mTabControl.getCurrentWebView();
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (view != null) {
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (gestZ) {
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (z < 0) {
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomOut();
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            } else {
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomIn();
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            view.flingScroll(0, Math.round(y * 100));
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
11850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
11860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastGestureTime = now;
11870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onAccuracyChanged(int sensor, int accuracy) {
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TODO Auto-generated method stub
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onResume() {
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
119931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12087bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
12107bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null) {
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // In case credential request never comes back
12200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
12270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.doFlick()) {
12290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSensorManager == null) {
12300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSensorManager = (SensorManager) getSystemService(
12310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Context.SENSOR_SERVICE);
12320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.registerListener(mSensorListener,
12340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_ACCELEROMETER,
12350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_DELAY_FASTEST);
12360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
12370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager = null;
12380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
12450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onSaveInstanceState(Bundle outState) {
124731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
12480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
12490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
12510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
12520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
12530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
12540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
12550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
12570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
12580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onPause() {
12610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
12620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
12640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
12650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12687bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
12690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
12707bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
12710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
12720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
12730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
12740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the credentials toast if it is up
12770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null && mCredsDlg.isShowing()) {
12780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
12790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
12810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
12830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
12850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
12860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
12870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSensorManager != null) {
12890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.unregisterListener(mSensorListener);
12900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onDestroy() {
129431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
12950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
12960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
12980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
12990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab t = mTabControl.getCurrentTab();
1300fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1301fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1302fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1303fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
13040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
13050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
13060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
13070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mGlsConnection != null) {
13080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            unbindService(mGlsConnection);
13090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mGlsConnection = null;
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
13130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // stop MASF proxy service
13140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
13150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
13160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
13170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //   (new ComponentName(
13180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
13190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
13200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //stopService(proxyServiceIntent);
1321b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
1322b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
13230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
13270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
13280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
13300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
13310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
13320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
13330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoFromShowSSLCertificateOnError.booleanValue());
13340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
13360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
13380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
13390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
13410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
13420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
13430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
13440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
13450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
13460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
13480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
13490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
13500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
13510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
13520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
13530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
13540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
13550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
13560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
13570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
13580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
13590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
13600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mFindDialog != null && mFindDialog.isShowing()) {
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mFindDialog.onConfigurationChanged(newConfig);
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public void onLowMemory() {
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13717bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean resumeWebViewTimers() {
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if ((!mActivityInPause && !mPageStarted) ||
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (mActivityInPause && mPageStarted)) {
13740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
13750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
13760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
13770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
13780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
13790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
13800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
13810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
13820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13857bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
13860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause && !mPageStarted) {
13870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
13880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
13900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
13910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
13920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
13930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
13940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
13950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
13990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called when we are launching for the first time. We
14000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * are waiting for the login credentials before loading Google home
14010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * pages. This way the user will be logged in straight away.
14020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
14030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void waitForCredentials() {
14040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show a toast
14050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = new ProgressDialog(this);
14060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setIndeterminate(true);
14070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
14080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the user cancels the operation, then cancel the Google
14090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Credentials request.
14100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
14110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.show();
14120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // We set a timeout for the retrieval of credentials in onResume()
14140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // as that is when we have freed up some CPU time to get
14150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the login credentials.
14160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
14190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If we have received the credentials or we have timed out and we are
14200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * showing the credentials dialog, then it is time to move on.
14210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
14220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resumeAfterCredentials() {
14230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg == null) {
14240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
14250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the toast
14280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg.isShowing()) {
14290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
14300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
14320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear any pending timeout
14340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
14350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the page
14370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
14380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
14390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.loadUrl(mSettings.getHomePage());
14400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Update the settings, need to do this last as it can take a moment
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to persist the settings. In the mean time we could be loading
14440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // content.
14450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setLoginInitialized(this);
14460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
14490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
14500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
14510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
14520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
14530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Cursor c = Browser.getAllBookmarks(mResolver);
14540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!c.moveToFirst()) {
14550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.deactivate();
14560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
14570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
14580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
14590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            do {
14600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = c.getString(urlIndex);
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                db.retainIconForPageUrl(url);
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } while (c.moveToNext());
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            c.deactivate();
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
14650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
14800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
14890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
14960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView webView = getTopWindow();
15090d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        if (null == webView) {
15100d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
15110d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final HashMap hrefMap = new HashMap();
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        hrefMap.put("webview", webView);
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Message msg = mHandler.obtainMessage(
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                FOCUS_NODE_HREF, id, 0, hrefMap);
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
15210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
15240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return onOptionsItemSelected(item);
15300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
15320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
15360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bundle.putString(SearchManager.SOURCE, source);
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
15424e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project     * Overriding this to insert a local information bundle
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onSearchRequested() {
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startSearch(null, false,
15474e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
15630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
15650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
15660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15670d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        if (null == mTabOverview && null == getTopWindow()) {
15680d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
15690d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.goto_menu_id: {
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = getTopWindow().getUrl();
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_GOTO), false);
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmarks_menu_id:
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(false);
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.windows_menu_id:
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getTabCount() == 1) {
1585f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    openTabAndShow(mSettings.getHomePage(), null, false, null);
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    tabPicker(true, mTabControl.getCurrentIndex(), false);
15880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final int currentIndex = mTabControl.getCurrentIndex();
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab parent =
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getCurrentTab().getParentTab();
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int indexToShow = -1;
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (parent != null) {
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    indexToShow = mTabControl.getTabIndex(parent);
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Get the last tab in the list. If it is the current tab,
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // subtract 1 more.
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    indexToShow = mTabControl.getTabCount() - 1;
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (currentIndex == indexToShow) {
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        indexToShow--;
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                switchTabs(currentIndex, indexToShow, true);
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TabControl.Tab current = mTabControl.getCurrentTab();
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current.getWebView().loadUrl(mSettings.getHomePage());
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.setWebView(getTopWindow());
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.show();
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(true);
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Browser.sendString(this, getTopWindow().getUrl());
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Tab menu
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_tab_menu_id:
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabOverview.setCurrentIndex(pos);
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabListener.onClick(pos);
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.remove_tab_menu_id:
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabListener.remove(pos);
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.new_tab_menu_id:
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No need to check for mTabOverview here since we are not
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // dependent on it for a position.
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null) {
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // If the overview happens to be non-null, make the "New
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Tab" cell visible.
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabOverview != null) {
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabOverview.setCurrentIndex(ImageGrid.NEW_TAB);
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabListener.onClick(ImageGrid.NEW_TAB);
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_tab_menu_id:
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    TabControl.Tab t = mTabControl.getTab(pos);
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Since we called populatePickerData for all of the
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // tabs, getTitle and getUrl will return appropriate
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // values.
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Browser.saveBookmark(BrowserActivity.this, t.getTitle(),
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            t.getUrl());
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.history_tab_menu_id:
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(true);
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmarks_tab_menu_id:
17300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(false);
17310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.properties_tab_menu_id:
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
17360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    showPageInfo(mTabControl.getTab(pos), false);
17370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
17510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            TabControl.Tab desiredTab = mTabControl.getTab(id);
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                switchTabs(mTabControl.getCurrentIndex(), id, false);
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
17590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
17660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
17710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
17740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
17750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onPrepareOptionsMenu(Menu menu)
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    {
17790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
17820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
17830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
17840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
17850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
17860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
17870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.TAB_MENU:
17880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
17890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
17900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
17910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
17920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.TAB_MENU, true);
17930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.TAB_MENU, true);
17940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean newT = mTabControl.getTabCount() < TabControl.MAX_TABS;
17960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem tab = menu.findItem(R.id.new_tab_menu_id);
17970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                tab.setVisible(newT);
17980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                tab.setEnabled(newT);
17990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
18010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
18020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
18030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
18040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
18050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.TAB_MENU, false);
18060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.TAB_MENU, false);
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
18100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
18110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
18120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
18130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
18140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.TAB_MENU, false);
18150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.TAB_MENU, false);
18160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
18180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
18190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
18200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
18210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
18220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
18230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
18240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
18250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
18270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
18280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
18300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
18310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
18330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
18340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
18360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
18380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // If there is only 1 window, the text will be "New window"
18430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem windows = menu.findItem(R.id.windows_menu_id);
18440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                windows.setTitleCondensed(mTabControl.getTabCount() > 1 ?
18450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getString(R.string.view_tabs_condensed) :
18460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getString(R.string.tab_picker_new_tab));
18470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
18490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
18500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
18510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
18520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
18550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
18560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
18590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
18600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
18610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
18620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
18630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
18640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
18650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
18680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
18690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
18700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
18710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
18720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
18740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
18750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
18760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
18790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
18800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
18810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
18820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
18830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
18850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
18860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
18870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
18880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
18890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
18900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
18910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
18920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
18930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
18940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
18950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
18960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
18970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
18980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
19000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
19050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
19060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
19070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
19080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.setType(Contacts.People.CONTENT_ITEM_TYPE);
19090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
19110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
19160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
19170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
19180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
19190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
19200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
19210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
19220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
19250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
19260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
19270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
19280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
19290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
19300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
19310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
19320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
19350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
19370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
19380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
19390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
19400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
19410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
19420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
19430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getTabCount() < TabControl.MAX_TABS);
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
19510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
19520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
19530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
19540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
19550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
19560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
19570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
19580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
19590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
19600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
19610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
19640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
19650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
19700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachTabToContentView(TabControl.Tab t) {
19710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView main = t.getWebView();
19720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the main WebView.
19730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(main, COVER_SCREEN_PARAMS);
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the sub window if necessary
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        attachSubWindow(t);
19760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
19770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachSubWindow(TabControl.Tab t) {
19820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If a sub window exists, attach it to the content view.
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView subView = t.getSubWebView();
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (subView != null) {
19850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final View container = t.getSubWebViewContainer();
19860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContentView.addView(container, COVER_SCREEN_PARAMS);
19870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            subView.requestFocus();
19880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
19920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void removeTabFromContentView(TabControl.Tab t) {
1993cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project        // Remove the main WebView.
19940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.removeView(t.getWebView());
19950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the sub window if it exists.
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (t.getSubWebView() != null) {
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContentView.removeView(t.getSubWebViewContainer());
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
20030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void dismissSubWindow(TabControl.Tab t) {
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView mainView = t.getWebView();
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (t.getSubWebView() != null) {
20060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Remove the container view and request focus on the main WebView.
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContentView.removeView(t.getSubWebViewContainer());
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mainView.requestFocus();
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Tell the TabControl to dismiss the subwindow. This will destroy
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the WebView.
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.dismissSubWindow(t);
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Send the ANIMTE_FROM_OVERVIEW message after changing the current tab.
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void sendAnimateFromOverview(final TabControl.Tab tab,
2017f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima            final boolean newTab, final UrlData urlData, final byte[] postData,
20188ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            final int delay, final Message msg) {
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Set the current tab.
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.setCurrentTab(tab);
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the WebView so it will layout.
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        attachTabToContentView(tab);
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Set the view to invisibile for now.
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        tab.getWebView().setVisibility(View.INVISIBLE);
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If there is a sub window, make it invisible too.
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (tab.getSubWebView() != null) {
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tab.getSubWebViewContainer().setVisibility(View.INVISIBLE);
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create our fake animating view.
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final AnimatingView view = new AnimatingView(this, tab);
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach it to the view system and make in invisible so it will
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // layout but not flash white on the screen.
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(view, COVER_SCREEN_PARAMS);
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        view.setVisibility(View.INVISIBLE);
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Send the animate message.
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final HashMap map = new HashMap();
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        map.put("view", view);
20380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the url after the AnimatingView has captured the picture. This
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // prevents any bad layout or bad scale from being used during
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // animation.
204125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        if (!urlData.isEmpty()) {
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dismissSubWindow(tab);
20438ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            if (postData != null) {
2044f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                tab.getWebView().postUrl(urlData.mUrl, postData);
20458ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            } else {
2046f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                urlData.loadIn(tab.getWebView());
20478ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            }
20480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        map.put("msg", msg);
20500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessageDelayed(mHandler.obtainMessage(
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ANIMATE_FROM_OVERVIEW, newTab ? 1 : 0, 0, map), delay);
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Increment the count to indicate that we are in an animation.
20530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mAnimationCount++;
20540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the listener so we don't get any more tab changes.
20550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview.setListener(null);
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabListener = null;
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the menu empty until the animation completes.
20580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = EMPTY_MENU;
20590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // 500ms animation with 800ms delay
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int TAB_ANIMATION_DURATION = 500;
20640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int TAB_OVERVIEW_DELAY     = 800;
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called by TabControl when a tab is requesting focus
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void showTab(TabControl.Tab t) {
2068f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project        showTab(t, null);
2069f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project    }
2070f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project
207125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private void showTab(TabControl.Tab t, UrlData urlData) {
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Disallow focus change during a tab animation.
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount > 0) {
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int delay = 0;
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabOverview == null) {
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Add a delay so the tab overview can be shown before the second
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // animation begins.
20800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
20810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tabPicker(false, mTabControl.getTabIndex(t), false);
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2083f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima        sendAnimateFromOverview(t, false, urlData, null, delay, null);
208425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    }
208525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
208625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // A wrapper function of {@link #openTabAndShow(UrlData, Message, boolean, String)}
208725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
2088f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima    private TabControl.Tab openTabAndShow(String url, final Message msg,
208925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            boolean closeOnExit, String appId) {
2090f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima        return openTabAndShow(new UrlData(url), msg, closeOnExit, appId);
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // url isn't null, it will load the given url. If the tab overview is not
20960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // showing, it will animate to the tab overview, create a new tab and
20970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // animate away from it. After the animation completes, it will dispatch
20980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // the given Message. If the tab overview is already showing (i.e. this
20990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // method is called from TabListener.onClick(), the method will animate
21000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // away from the tab overview.
2101f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima    private TabControl.Tab openTabAndShow(UrlData urlData, final Message msg,
2102f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            boolean closeOnExit, String appId) {
21030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final boolean newTab = mTabControl.getTabCount() != TabControl.MAX_TABS;
21040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab currentTab = mTabControl.getCurrentTab();
21050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (newTab) {
21060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int delay = 0;
21070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the tab overview is up and there are animations, just load
21080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the url.
21090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mTabOverview != null && mAnimationCount > 0) {
211025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if (!urlData.isEmpty()) {
21110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // We should not have a msg here since onCreateWindow
21120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // checks the animation count and every other caller passes
21130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // null.
21140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    assert msg == null;
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // just dismiss the subwindow and load the given url.
21160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(currentTab);
211725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    urlData.loadIn(currentTab.getWebView());
21180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // show mTabOverview if it is not there.
21210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabOverview == null) {
21220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // We have to delay the animation from the tab picker by the
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // length of the tab animation. Add a delay so the tab
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // overview can be shown before the second animation begins.
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    tabPicker(false, ImageGrid.NEW_TAB, false);
21270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Animate from the Tab overview after any animations have
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // finished.
2130c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                final TabControl.Tab tab = mTabControl.createNewTab(
2131f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                        closeOnExit, appId, urlData.mUrl);
2132f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                sendAnimateFromOverview(tab, true, urlData, null, delay, msg);
2133c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                return tab;
21340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
213525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        } else if (!urlData.isEmpty()) {
21360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We should not have a msg here.
21370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            assert msg == null;
21380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mTabOverview != null && mAnimationCount == 0) {
2139f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                sendAnimateFromOverview(currentTab, false, urlData, null,
21400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        TAB_OVERVIEW_DELAY, null);
21410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Get rid of the subwindow if it exists
21430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                dismissSubWindow(currentTab);
21440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Load the given url.
214525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData.loadIn(currentTab.getWebView());
21460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2148c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba        return currentTab;
21490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Animation createTabAnimation(final AnimatingView view,
21520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final View cell, boolean scaleDown) {
21530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final AnimationSet set = new AnimationSet(true);
21540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final float scaleX = (float) cell.getWidth() / view.getWidth();
21550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final float scaleY = (float) cell.getHeight() / view.getHeight();
21560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (scaleDown) {
21570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new ScaleAnimation(1.0f, scaleX, 1.0f, scaleY));
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new TranslateAnimation(0, cell.getLeft(), 0,
21590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    cell.getTop()));
21600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
21610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new ScaleAnimation(scaleX, 1.0f, scaleY, 1.0f));
21620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new TranslateAnimation(cell.getLeft(), 0,
21630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    cell.getTop(), 0));
21640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        set.setDuration(TAB_ANIMATION_DURATION);
21660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        set.setInterpolator(new DecelerateInterpolator());
21670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return set;
21680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Animate to the tab overview. currentIndex tells us which position to
21710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // animate to and newIndex is the position that should be selected after
21720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // the animation completes.
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If remove is true, after the animation stops, a confirmation dialog will
21740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be displayed to the user.
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void animateToTabOverview(final int newIndex, final boolean remove,
21760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AnimatingView view) {
21770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Find the view in the ImageGrid allowing for the "New Tab" cell.
21780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int position = mTabControl.getTabIndex(view.mTab);
21790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
21800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            position++;
21810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Offset the tab position with the first visible position to get a
21840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // number between 0 and 3.
21850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        position -= mTabOverview.getFirstVisiblePosition();
21860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Grab the view that we are going to animate to.
21880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = mTabOverview.getChildAt(position);
21890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Animation.AnimationListener l =
21910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new Animation.AnimationListener() {
21920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationStart(Animation a) {
21930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabOverview.requestFocus();
21940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // Clear the listener so we don't trigger a tab
21950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // selection.
21960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabOverview.setListener(null);
21970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
21980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationRepeat(Animation a) {}
21990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationEnd(Animation a) {
22000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // We are no longer animating so decrement the count.
22010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mAnimationCount--;
22020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // Make the view GONE so that it will not draw between
22030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // now and when the Runnable is handled.
22040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        view.setVisibility(View.GONE);
22050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // Post a runnable since we can't modify the view
22060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // hierarchy during this callback.
22070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.post(new Runnable() {
22080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void run() {
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Remove the AnimatingView.
22100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mContentView.removeView(view);
22110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (mTabOverview != null) {
22120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Make newIndex visible.
22130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    mTabOverview.setCurrentIndex(newIndex);
22140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Restore the listener.
22150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    mTabOverview.setListener(mTabListener);
22160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Change the menu to TAB_MENU if the
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // ImageGrid is interactive.
22180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    if (mTabOverview.isLive()) {
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mMenuState = R.id.TAB_MENU;
22200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabOverview.requestFocus();
22210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    }
22220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
22230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // If a remove was requested, remove the tab.
22240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (remove) {
22250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // During a remove, the current tab has
22260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // already changed. Remember the current one
22270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // here.
22280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    final TabControl.Tab currentTab =
22290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            mTabControl.getCurrentTab();
22300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Remove the tab at newIndex from
22310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // TabControl and the tab overview.
22320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    final TabControl.Tab tab =
22330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            mTabControl.getTab(newIndex);
22340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    mTabControl.removeTab(tab);
22350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Restore the current tab.
22360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    if (currentTab != tab) {
22370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabControl.setCurrentTab(currentTab);
22380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    }
22390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    if (mTabOverview != null) {
22400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabOverview.remove(newIndex);
22410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        // Make the current tab visible.
22420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabOverview.setCurrentIndex(
22430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                                mTabControl.getCurrentIndex());
22440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    }
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
22460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        });
22480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                };
22500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Do an animation if there is a view to animate to.
22520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (v != null) {
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create our animation
22540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Animation anim = createTabAnimation(view, v, true);
22550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.setAnimationListener(l);
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Start animating
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            view.startAnimation(anim);
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If something goes wrong and we didn't find a view to animate to,
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just do everything here.
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l.onAnimationStart(null);
22620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l.onAnimationEnd(null);
22630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Animate from the tab picker. The index supplied is the index to animate
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // from.
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void animateFromTabOverview(final AnimatingView view,
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final boolean newTab, final Message msg) {
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // firstVisible is the first visible tab on the screen.  This helps
22710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to know which corner of the screen the selected tab is.
22720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int firstVisible = mTabOverview.getFirstVisiblePosition();
22730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // tabPosition is the 0-based index of of the tab being opened
22740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int tabPosition = mTabControl.getTabIndex(view.mTab);
22750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Add one to make room for the "New Tab" cell.
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tabPosition++;
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If this is a new tab, animate from the "New Tab" cell.
22800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (newTab) {
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tabPosition = 0;
22820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Location corresponds to the four corners of the screen.
22840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // A new tab or 0 is upper left, 0 for an old tab is upper
22850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // right, 1 is lower left, and 2 is lower right
22860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int location = tabPosition - firstVisible;
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Find the view at this location.
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = mTabOverview.getChildAt(location);
22900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Wait until the animation completes to replace the AnimatingView.
22920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Animation.AnimationListener l =
22930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new Animation.AnimationListener() {
22940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationStart(Animation a) {}
22950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationRepeat(Animation a) {}
22960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationEnd(Animation a) {
22970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.post(new Runnable() {
22980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void run() {
22990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mContentView.removeView(view);
23000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Dismiss the tab overview. If the cell at the
23010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // given location is null, set the fade
23020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // parameter to true.
23030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                dismissTabOverview(v == null);
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                TabControl.Tab t =
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabControl.getCurrentTab();
23060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mMenuState = R.id.MAIN_MENU;
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Resume regular updates.
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                t.getWebView().resumeTimers();
23090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Dispatch the message after the animation
23100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // completes.
23110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (msg != null) {
23120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    msg.sendToTarget();
23130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
23140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // The animation is done and the tab overview is
23150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // gone so allow key events and other animations
23160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // to begin.
23170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mAnimationCount--;
23180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Reset all the title bar info.
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                resetTitle();
23200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        });
23220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                };
23240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (v != null) {
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Animation anim = createTabAnimation(view, v, false);
23270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Set the listener and start animating
23280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.setAnimationListener(l);
23290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            view.startAnimation(anim);
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Make the view VISIBLE during the animation.
23310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            view.setVisibility(View.VISIBLE);
23320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Go ahead and do all the cleanup.
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l.onAnimationEnd(null);
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dismiss the tab overview applying a fade if needed.
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void dismissTabOverview(final boolean fade) {
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fade) {
23410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f);
23420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.setDuration(500);
23430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.startNow();
23440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabOverview.startAnimation(anim);
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case there was a problem with animating away from the tab
23470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // overview
23480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
23490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current != null) {
23500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current.setVisibility(View.VISIBLE);
23510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
23520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "No current WebView in dismissTabOverview");
23530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the sub window container visible.
23550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabControl.getCurrentSubWindow() != null) {
23560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.getCurrentTab().getSubWebViewContainer()
23570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setVisibility(View.VISIBLE);
23580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.removeView(mTabOverview);
23602ed6edb70dae14691de2109e97fd54feedd84464Patrick Scott        // Clear all the data for tab picker so next time it will be
23612ed6edb70dae14691de2109e97fd54feedd84464Patrick Scott        // recreated.
23622ed6edb70dae14691de2109e97fd54feedd84464Patrick Scott        mTabControl.wipeAllPickerData();
23630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview.clear();
23640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview = null;
23650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabListener = null;
23660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2368c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba    private TabControl.Tab openTab(String url) {
23690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
2370f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            TabControl.Tab t = mTabControl.createNewTab();
23710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
23720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                t.getWebView().loadUrl(url);
23730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2374c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
23750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
2376c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return openTabAndShow(url, null, false, null);
23770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
23810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
23820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
23840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
23850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
23860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
23890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
23900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
23940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
23950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
23970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
23980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
23990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
24020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
24030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
24070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
24080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
24090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
24100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
24110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
24130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
24140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be (for example, if we
24190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * load a page from history).
24200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitle() {
24220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetLockIcon();
24230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
24240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
24280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
24290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
24300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
24310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
24320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
24330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
24350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        revertLockIcon();
24360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
24370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
24410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
24430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
24440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
24450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
24460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
24480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
24490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebChromeClient.onProgressChanged(current, progress);
24500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
24530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
24540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
24550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
24560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(item.getUrl(), item.getTitle());
24570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
24580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
24590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(null, null);
24600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
24610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
24660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
24670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
24680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setUrlTitle(String url, String title) {
24700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
24710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
24720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // While the tab overview is animating or being shown, block changes
24740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to the title.
24750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount == 0 && mTabOverview == null) {
247681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            if (CUSTOM_BROWSER_BAR) {
247781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                mTitleBar.setTitleAndUrl(title, url);
247881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            } else {
247981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                setTitle(buildUrlTitle(url, title));
248081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            }
24810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Builds and returns the page title, which is some
24860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * combination of the page URL and title.
24870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
24880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
24890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The page title.
24900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String buildUrlTitle(String url, String title) {
24920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String urlTitle = "";
24930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
24950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String titleUrl = buildTitleUrl(url);
24960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (title != null && 0 < title.length()) {
24980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (titleUrl != null && 0 < titleUrl.length()) {
24990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    urlTitle = titleUrl + ": " + title;
25000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
25010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    urlTitle = title;
25020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
25040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (titleUrl != null) {
25050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    urlTitle = titleUrl;
25060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return urlTitle;
25110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
25140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
25150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
25160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
25170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
25180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
25190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
25200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
252132e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
25220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
25230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
25250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
25260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
25270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
25280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
25290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
25300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
25320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
25330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
25350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
25360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
25370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
25380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
25390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
25400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
25410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
25420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
25450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
25480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
25510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setFavicon(Bitmap icon) {
25520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // While the tab overview is animating or being shown, block changes to
25530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the favicon.
25540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount > 0 || mTabOverview != null) {
25550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
25560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
255781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        if (CUSTOM_BROWSER_BAR) {
255881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            Drawable[] array = new Drawable[3];
255981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            array[0] = new PaintDrawable(Color.BLACK);
256081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            PaintDrawable p = new PaintDrawable(Color.WHITE);
256181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            array[1] = p;
256281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            if (icon == null) {
256381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                array[2] = mGenericFavicon;
256481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            } else {
256581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                array[2] = new BitmapDrawable(icon);
256681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            }
256781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            LayerDrawable d = new LayerDrawable(array);
256881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            d.setLayerInset(1, 1, 1, 1, 1);
256981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            d.setLayerInset(2, 2, 2, 2, 2);
257081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            mTitleBar.setFavicon(d);
25710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
257281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            Drawable[] array = new Drawable[2];
257381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            PaintDrawable p = new PaintDrawable(Color.WHITE);
257481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            p.setCornerRadius(3f);
257581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            array[0] = p;
257681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            if (icon == null) {
257781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                array[1] = mGenericFavicon;
257881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            } else {
257981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                array[1] = new BitmapDrawable(icon);
258081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            }
258181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            LayerDrawable d = new LayerDrawable(array);
258281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            d.setLayerInset(1, 2, 2, 2, 2);
258381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, d);
25840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
25880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Saves the current lock-icon state before resetting
25890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the lock icon. If we have an error, we may need to
25900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * roll back to the previous state.
25910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
25920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void saveLockIcon() {
25930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPrevLockType = mLockIconType;
25940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
25970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reverts the lock-icon state to the last saved state,
25980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * for example, if we had an error, and need to cancel
25990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the load.
26000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
26010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void revertLockIcon() {
26020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = mPrevLockType;
26030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
260431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
26050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.revertLockIcon:" +
26060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  " revert lock icon to " + mLockIconType);
26070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(mLockIconType);
26100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void switchTabs(int indexFrom, int indexToShow, boolean remove) {
26130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
26140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Animate to the tab picker, remove the current tab, then
26150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // animate away from the tab picker to the parent WebView.
26160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        tabPicker(false, indexFrom, remove);
26170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Change to the parent tab
26180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab tab = mTabControl.getTab(indexToShow);
26190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (tab != null) {
26208ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            sendAnimateFromOverview(tab, false, null, null, delay, null);
26210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
26220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Increment this here so that no other animations can happen in
26230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // between the end of the tab picker transition and the beginning
26240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // of openTabAndShow. This has a matching decrement in the handler
26250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // of OPEN_TAB_AND_SHOW.
26260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mAnimationCount++;
26270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Send a message to open a new tab.
26280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(
26290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mHandler.obtainMessage(OPEN_TAB_AND_SHOW,
26300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mSettings.getHomePage()), delay);
26310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void goBackOnePageOrQuit() {
26350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
26360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
26370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
26380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
26390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
26400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
26410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
26420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
26430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
26440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
26450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
26470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
26480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
26490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
26500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
26510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
26520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            TabControl.Tab parent = current.getParentTab();
26530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
26540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                switchTabs(mTabControl.getCurrentIndex(),
26550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getTabIndex(parent), true);
26560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
26570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
26580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
26590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
26600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
26610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26627bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
26637bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
26647bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
26650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
26660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
26670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
26690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
26700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
26710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
26720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
26730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
26740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
26750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
26760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public KeyTracker.State onKeyTracker(int keyCode,
26810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                         KeyEvent event,
26820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                         KeyTracker.Stage stage,
26830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                         int duration) {
26840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if onKeyTracker() is called after activity onStop()
26850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // because of accumulated key events,
26860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // we should ignore it as browser is not active any more.
26870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView topWindow = getTopWindow();
26880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (topWindow == null)
26890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return KeyTracker.State.NOT_TRACKING;
26900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_BACK) {
26920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // During animations, block the back key so that other animations
26930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not triggered and so that we don't end up destroying all the
26940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // WebViews before finishing the animation.
26950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAnimationCount > 0) {
26960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return KeyTracker.State.DONE_TRACKING;
26970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (stage == KeyTracker.Stage.LONG_REPEAT) {
26990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(true);
27000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return KeyTracker.State.DONE_TRACKING;
27010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (stage == KeyTracker.Stage.UP) {
27020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // FIXME: Currently, we do not have a notion of the
27030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // history picker for the subwindow, but maybe we
27040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // should?
27050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView subwindow = mTabControl.getCurrentSubWindow();
27060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (subwindow != null) {
27070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (subwindow.canGoBack()) {
27080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        subwindow.goBack();
27090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
27100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dismissSubWindow(mTabControl.getCurrentTab());
27110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
27130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    goBackOnePageOrQuit();
27140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return KeyTracker.State.DONE_TRACKING;
27160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return KeyTracker.State.KEEP_TRACKING;
27180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return KeyTracker.State.NOT_TRACKING;
27200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
27230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_MENU) {
27240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mMenuIsDown = true;
27250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean handled =  mKeyTracker.doKeyDown(keyCode, event);
27270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!handled) {
27280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (keyCode) {
27290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case KeyEvent.KEYCODE_SPACE:
27300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (event.isShiftPressed()) {
27310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getTopWindow().pageUp(false);
27320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
27330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getTopWindow().pageDown(false);
27340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    handled = true;
27360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                default:
27390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return handled || super.onKeyDown(keyCode, event);
27430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
27460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_MENU) {
27470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mMenuIsDown = false;
27480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mKeyTracker.doKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
27500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void stopLoading() {
27530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
27540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
27550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
27560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebViewClient.onPageFinished(w, w.getUrl());
27570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
27590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
27600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
27610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
27620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
27650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
27660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
27670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
27680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // called by a non-UI thread to post the message
27720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void postMessage(int what, int arg1, int arg2, Object obj) {
27730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2, obj));
27740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
27770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
27780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
27790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
27810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
27820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CANCEL_CREDS_REQUEST    = 103;
27830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int ANIMATE_FROM_OVERVIEW   = 104;
27840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int ANIMATE_TO_OVERVIEW     = 105;
27850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int OPEN_TAB_AND_SHOW       = 106;
27860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CHECK_MEMORY            = 107;
27870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int RELEASE_WAKELOCK        = 108;
27880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
27900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
27910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
27930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
27940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case ANIMATE_FROM_OVERVIEW:
27950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    final HashMap map = (HashMap) msg.obj;
27960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    animateFromTabOverview((AnimatingView) map.get("view"),
27970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            msg.arg1 == 1, (Message) map.get("msg"));
27980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case ANIMATE_TO_OVERVIEW:
28010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    animateToTabOverview(msg.arg1, msg.arg2 == 1,
28020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            (AnimatingView) msg.obj);
28030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case OPEN_TAB_AND_SHOW:
28060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Decrement mAnimationCount before openTabAndShow because
28070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // the method relies on the value being 0 to start the next
28080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // animation.
28090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mAnimationCount--;
2810f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    openTabAndShow((String) msg.obj, null, false, null);
28110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
28140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
28150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
28160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
28170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
28190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
28200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
28210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
28220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
28230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
28250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
28260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
28270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            loadURL(getTopWindow(), url);
28280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
2830c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            final TabControl.Tab parent = mTabControl
2831c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                    .getCurrentTab();
2832c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            final TabControl.Tab newTab = openTab(url);
2833c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2834c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2835c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
28360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
28380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
28390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
28400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
28410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
28420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
28440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Browser.sendString(BrowserActivity.this, url);
28450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
28470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
28480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
28500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
28510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
28520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
28570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    loadURL(getTopWindow(), (String) msg.obj);
28580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
28610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
28620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CANCEL_CREDS_REQUEST:
28650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    resumeAfterCredentials();
28660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CHECK_MEMORY:
28690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // reschedule to check memory condition
28700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mHandler.removeMessages(CHECK_MEMORY);
28710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mHandler.sendMessageDelayed(mHandler.obtainMessage
28720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            (CHECK_MEMORY), CHECK_MEMORY_INTERVAL);
28730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    checkMemory();
28740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
28770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
28780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
28790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
28820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
28830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
28840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
28860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebViewClient implementation.
28870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
28880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
28910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
28930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
28940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebViewClient getWebViewClient() {
28960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebViewClient;
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateIcon(String url, Bitmap icon) {
29000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (icon != null) {
29010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
29020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url, icon);
29030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setFavicon(icon);
29050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebViewClient mWebViewClient = new WebViewClient() {
29080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
29090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageStarted(WebView view, String url, Bitmap favicon) {
29100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetLockIcon(url);
29110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(url, null);
29120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Call updateIcon instead of setFavicon so the bookmark
29130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // database can be updated.
29140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateIcon(url, favicon);
29150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSettings.isTracing() == true) {
29170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // FIXME: we should save the trace file somewhere other than data.
29180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // I can't use "/tmp" as it competes for system memory.
29190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                File file = getDir("browserTrace", 0);
29200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String baseDir = file.getPath();
29210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!baseDir.endsWith(File.separator)) baseDir += File.separator;
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String host;
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebAddress uri = new WebAddress(url);
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    host = uri.mHost;
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (android.net.ParseException ex) {
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    host = "unknown_host";
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                host = host.replace('.', '_');
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                baseDir = baseDir + host;
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                file = new File(baseDir+".data");
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (file.exists() == true) {
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    file.delete();
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                file = new File(baseDir+".key");
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (file.exists() == true) {
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    file.delete();
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = true;
29400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Debug.startMethodTracing(baseDir, 8 * 1024 * 1024);
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
29450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mStart = SystemClock.uptimeMillis();
29460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mProcessStart = Process.getElapsedCpuTime();
29470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
29490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
29500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mUserStart = sysCpu[0] + sysCpu[1];
29510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSystemStart = sysCpu[2];
29520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIdleStart = sysCpu[3];
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
29540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mUiStart = SystemClock.currentThreadTimeMillis();
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mPageStarted) {
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = true;
29607bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // if onResume() has been called, resumeWebViewTimers() does
29617bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // nothing.
29627bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                resumeWebViewTimers();
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // reset sync timer to avoid sync starts during loading a page
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().resetSync();
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mInLoad = true;
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateInLoadMenuItems();
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mIsNetworkUp) {
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ( mAlertDialog == null) {
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mAlertDialog = new AlertDialog.Builder(BrowserActivity.this)
29730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.loadSuspendedTitle)
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.loadSuspended)
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (view != null) {
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    view.setNetworkAvailable(false);
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // schedule to check memory condition
29840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler.obtainMessage(CHECK_MEMORY),
29850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CHECK_MEMORY_INTERVAL);
29860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
29890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageFinished(WebView view, String url) {
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Reset the title and icon in case we stopped a provisional
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // load.
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(view);
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Update the lock icon image only once we are done loading
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateLockIconImage(mLockIconType);
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
2998cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project            if (false) {
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String uiInfo = "UI thread used "
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.currentThreadTimeMillis() - mUiStart)
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms";
300531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
30060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, uiInfo);
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //The string that gets written to the log
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String performanceString = "It took total "
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.uptimeMillis() - mStart)
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms clock time to load the page."
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + "\nbrowser process used "
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (Process.getElapsedCpuTime() - mProcessStart)
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, user processes used "
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, kernel used "
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[2] - mSystemStart) * 10
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
30190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms and irq took "
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
30210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            * 10 + " ms, " + uiInfo;
302231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
30230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
30240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url != null) {
30260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // strip the url to maintain consistency
30270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String newUrl = new String(url);
30280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (newUrl.startsWith("http://www.")) {
30290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(11);
30300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("http://")) {
30310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(7);
30320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://www.")) {
30330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(12);
30340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://")) {
30350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(8);
30360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
303731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGD_ENABLED) {
30380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.d(LOGTAG, newUrl + " loaded");
30390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        /*
30410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (sWhiteList.contains(newUrl)) {
30420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // The string that gets pushed to the statistcs
30430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // service
30440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            performanceString = performanceString
30450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nWebpage: "
30460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + newUrl
30470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nCarrier: "
30480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + android.os.SystemProperties
30490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            .get("gsm.sim.operator.alpha");
30500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (mWebView != null
30510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext() != null
30520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext().getSystemService(
30530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Context.CONNECTIVITY_SERVICE) != null) {
30540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                ConnectivityManager cManager =
30550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (ConnectivityManager) mWebView
30560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getContext().getSystemService(
30570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        Context.CONNECTIVITY_SERVICE);
30580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                NetworkInfo nInfo = cManager
30590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getActiveNetworkInfo();
30600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (nInfo != null) {
30610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString = performanceString
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + "\nNetwork Type: "
30630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + nInfo.getType().toString();
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Checkin.logEvent(mResolver,
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Checkin.Events.Tag.WEBPAGE_LOAD,
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString);
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.w(LOGTAG, "pushed to the statistics service");
30700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        */
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             }
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mInTrace) {
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = false;
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Debug.stopMethodTracing();
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mPageStarted) {
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = false;
30837bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // pauseWebViewTimers() will do nothing and return false if
30847bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // onPause() is not called yet.
30857bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                if (pauseWebViewTimers()) {
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
30870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.removeMessages(RELEASE_WAKELOCK);
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(CHECK_MEMORY);
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            checkMemory();
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // return true if want to hijack the url to let another app to handle it
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideUrlLoading(WebView view, String url) {
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith(SCHEME_WTAI)) {
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/mc;number
31020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_MC)) {
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent intent = new Intent(Intent.ACTION_VIEW,
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Uri.parse(WebView.SCHEME_TEL +
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            url.substring(SCHEME_WTAI_MC.length())));
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    startActivity(intent);
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/sd;dtmf
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // dtmf=string(dialstring)
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_SD)) {
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // only send when there is active voice connection
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/ap;number;name
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // name=string
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_AP)) {
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Uri uri;
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
31280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                uri = Uri.parse(url);
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IllegalArgumentException ex) {
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // check whether other activities want to handle this url
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.addCategory(Intent.CATEGORY_BROWSABLE);
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (startActivityIfNeeded(intent, -1)) {
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (ActivityNotFoundException ex) {
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // ignore the error. If no application can handle the URL,
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // eg about:blank, assume the browser can handle it.
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                openTab(url);
31470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                closeOptionsMenu();
31480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
31490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Updates the lock icon. This method is called when we discover another
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * resource to be loaded for this page (for example, javascript). While
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we update the icon type, we do not update the lock icon itself until
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we are done loading, it is slightly more secure this way.
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onLoadResource(WebView view, String url) {
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url != null && url.length() > 0) {
31630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // It is only if the page claims to be secure
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // that we may have to update the lock:
31650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mLockIconType == LOCK_ICON_SECURE) {
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // If NOT a 'safe' url, change the lock to mixed content!
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url) || URLUtil.isAboutUrl(url))) {
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mLockIconType = LOCK_ICON_MIXED;
316931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(LOGTAG, "BrowserActivity.updateLockIcon:" +
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                  " updated lock icon to " + mLockIconType + " due to " + url);
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show the dialog, asking the user if they would like to continue after
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * an excessive number of HTTP redirects.
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onTooManyRedirects(WebView view, final Message cancelMsg,
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final Message continueMsg) {
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameRedirect)
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrame307Post)
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        continueMsg.sendToTarget();
31910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
31920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
31930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
31940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
31950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
31960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
31970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
31980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
31990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
320337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        // Container class for the next error dialog that needs to be
320437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        // displayed.
320537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        class ErrorDialog {
320637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final int mTitle;
320737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final String mDescription;
320837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final int mError;
320937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            ErrorDialog(int title, String desc, int error) {
321037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mTitle = title;
321137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mDescription = desc;
321237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mError = error;
321337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
321437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        };
321537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
321637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void processNextError() {
321737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors == null) {
321837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                return;
321937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
322037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            // The first one is currently displayed so just remove it.
322137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            mQueuedErrors.removeFirst();
322237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors.size() == 0) {
322337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mQueuedErrors = null;
322437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                return;
322537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
322637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            showError(mQueuedErrors.getFirst());
322737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
322837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
322937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private DialogInterface.OnDismissListener mDialogListener =
323037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                new DialogInterface.OnDismissListener() {
323137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    public void onDismiss(DialogInterface d) {
323237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                        processNextError();
323337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    }
323437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                };
323537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private LinkedList<ErrorDialog> mQueuedErrors;
323637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
323737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void queueError(int err, String desc) {
323837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors == null) {
323937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mQueuedErrors = new LinkedList<ErrorDialog>();
324037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
324137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            for (ErrorDialog d : mQueuedErrors) {
324237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                if (d.mError == err) {
324337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    // Already saw a similar error, ignore the new one.
324437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    return;
324537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                }
324637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
324737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            ErrorDialog errDialog = new ErrorDialog(
324837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    err == EventHandler.FILE_NOT_FOUND_ERROR ?
324937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    R.string.browserFrameFileErrorLabel :
325037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    R.string.browserFrameNetworkErrorLabel,
325137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    desc, err);
325237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            mQueuedErrors.addLast(errDialog);
325337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
325437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            // Show the dialog now if the queue was empty.
325537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors.size() == 1) {
325637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                showError(errDialog);
325737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
325837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
325937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
326037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void showError(ErrorDialog errDialog) {
326137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            AlertDialog d = new AlertDialog.Builder(BrowserActivity.this)
326237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setTitle(errDialog.mTitle)
326337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setMessage(errDialog.mDescription)
326437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setPositiveButton(R.string.ok, null)
326537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .create();
326637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            d.setOnDismissListener(mDialogListener);
326737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            d.show();
326837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
326937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show a dialog informing the user of the network error reported by
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * WebCore.
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedError(WebView view, int errorCode,
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String description, String failingUrl) {
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (errorCode != EventHandler.ERROR_LOOKUP &&
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.ERROR_CONNECT &&
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.ERROR_BAD_URL &&
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.ERROR_UNSUPPORTED_SCHEME &&
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.FILE_ERROR) {
328237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                queueError(errorCode, description);
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
328437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
328537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    + " " + description);
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We need to reset the title after an error.
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndRevertLockIcon();
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Check with the user if it is ok to resend POST data as the page they
32930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * are trying to navigate to is the result of a POST.
32940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
32950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
32960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onFormResubmission(WebView view, final Message dontResend,
32970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                       final Message resend) {
32980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
32990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameFormResubmitLabel)
33000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrameFormResubmitMessage)
33010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
33020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
33030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        resend.sendToTarget();
33040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
33050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
33060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
33070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
33080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
33090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
33100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
33110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
33120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
33130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
33140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
33170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Insert the url into the visited history database.
33180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param url The url to be inserted.
33190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param isReload True if this url is being reloaded.
33200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * FIXME: Not sure what to do when reloading the page.
33210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
33220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
33230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void doUpdateVisitedHistory(WebView view, String url,
33240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isReload) {
33250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.regionMatches(true, 0, "about:", 0, 6)) {
33260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
33270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
33280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Browser.updateVisitedHistory(mResolver, url, true);
33290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebIconDatabase.getInstance().retainIconForPageUrl(url);
33300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
33330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Displays SSL error(s) dialog to the user.
33340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
33350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
33360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedSslError(
33370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final WebView view, final SslErrorHandler handler, final SslError error) {
33380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSettings.showSecurityWarnings()) {
33400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LayoutInflater factory =
33410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LayoutInflater.from(BrowserActivity.this);
33420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final View warningsView =
33430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    factory.inflate(R.layout.ssl_warnings, null);
33440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LinearLayout placeholder =
33450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
33460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_UNTRUSTED)) {
33480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
33490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
33500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
33510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_untrusted);
33520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
33530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
33540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_IDMISMATCH)) {
33560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
33570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
33580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
33590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_mismatch);
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_EXPIRED)) {
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_expired);
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_NOTYETVALID)) {
33720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
33740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
33750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_not_yet_valid);
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.security_warning)
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setView(warningsView)
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.ssl_continue,
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.proceed();
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNeutralButton(R.string.view_certificate,
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    showSSLCertificateOnError(view, handler, error);
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.cancel,
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setOnCancelListener(
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnCancelListener() {
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onCancel(DialogInterface dialog) {
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .show();
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed();
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Handles an HTTP authentication request.
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param handler The authentication handler
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param host The host
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param realm The realm
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedHttpAuthRequest(WebView view,
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final HttpAuthHandler handler, final String host, final String realm) {
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String username = null;
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = null;
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean reuseHttpAuthUsernamePassword =
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.useHttpAuthUsernamePassword();
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (reuseHttpAuthUsernamePassword &&
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (mTabControl.getCurrentWebView() != null)) {
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String[] credentials =
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getCurrentWebView()
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .getHttpAuthUsernamePassword(host, realm);
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (credentials != null && credentials.length == 2) {
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    username = credentials[0];
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    password = credentials[1];
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (username != null && password != null) {
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed(username, password);
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showHttpAuthentication(handler, host, realm, null, null, null, 0);
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only check shortcut key when MENU is held
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return getWindow().isShortcutKey(event.getKeyCode(), event);
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (view != mTabControl.getCurrentTopWebView()) {
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (event.isDown()) {
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyDown(event.getKeyCode(), event);
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyUp(event.getKeyCode(), event);
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebChromeClient implementation
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebChromeClient getWebChromeClient() {
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebChromeClient;
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Helper method to create a new tab or sub window.
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private void createWindow(final boolean dialog, final Message msg) {
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog) {
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabControl.createSubWindow();
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab t = mTabControl.getCurrentTab();
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                attachSubWindow(t);
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(t.getSubWebView());
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg.sendToTarget();
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab parent = mTabControl.getCurrentTab();
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // openTabAndShow will dispatch the message after creating the
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // new WebView. This will prevent another request from coming
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // in during the animation.
3496f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                final TabControl.Tab newTab = openTabAndShow((String) null, msg, false,
3497c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                        null);
3498c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                if (newTab != parent) {
3499c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                    parent.addChildTab(newTab);
3500c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                }
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(mTabControl.getCurrentWebView());
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onCreateWindow(WebView view, final boolean dialog,
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final boolean userGesture, final Message resultMsg) {
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Ignore these requests during tab animations or if the tab
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // overview is showing.
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAnimationCount > 0 || mTabOverview != null) {
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
35140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if we can't create any more tabs or sub windows.
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog && mTabControl.getCurrentSubWindow() != null) {
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_subwindows_dialog_title)
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_subwindows_dialog_message)
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (mTabControl.getTabCount() >= TabControl.MAX_TABS) {
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_windows_dialog_title)
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_windows_dialog_message)
35290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
35300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if this was a user gesture.
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (userGesture) {
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // createWindow will call openTabAndShow for new Windows and
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // that will call tabPicker which will increment
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // mAnimationCount.
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                createWindow(dialog, resultMsg);
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Allow the popup and create the appropriate window.
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener allowListener =
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
35460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d,
35470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                int which) {
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // Same comment as above for setting
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // mAnimationCount.
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            createWindow(dialog, resultMsg);
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // Since we incremented mAnimationCount while the
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // dialog was up, we have to decrement it here.
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mAnimationCount--;
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Block the popup by returning a null WebView.
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener blockListener =
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d, int which) {
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            resultMsg.sendToTarget();
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // We are not going to trigger an animation so
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // unblock keys and animation requests.
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mAnimationCount--;
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Build a confirmation dialog to display to the user.
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog d =
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.Builder(BrowserActivity.this)
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.attention)
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
35730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setMessage(R.string.popup_window_attempt)
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.allow, allowListener)
35750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.block, blockListener)
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setCancelable(false)
35770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .create();
35780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Show the confirmation dialog.
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d.show();
35810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We want to increment mAnimationCount here to prevent a
35820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // potential race condition. If the user allows a pop-up from a
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // site and that pop-up then triggers another pop-up, it is
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // possible to get the BACK key between here and when the dialog
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // appears.
35860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mAnimationCount++;
35870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
35880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onCloseWindow(WebView window) {
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final int currentIndex = mTabControl.getCurrentIndex();
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab parent =
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getCurrentTab().getParentTab();
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // JavaScript can only close popup window.
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                switchTabs(currentIndex, mTabControl.getTabIndex(parent), true);
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onProgressChanged(WebView view, int newProgress) {
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Block progress updates to the title bar while the tab overview
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // is animating or being displayed.
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAnimationCount == 0 && mTabOverview == null) {
360681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                if (CUSTOM_BROWSER_BAR) {
360781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                    mTitleBar.setProgress(newProgress);
360881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                } else {
360981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                    getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
361081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                            newProgress * 100);
361181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
361281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                }
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (newProgress == 100) {
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // onProgressChanged() is called for sub-frame too while
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // onPageFinished() is only called for the main frame. sync
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // cookie and cache promptly here.
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CookieSyncManager.getInstance().sync();
3620cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                if (mInLoad) {
3621cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    mInLoad = false;
3622cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    updateInLoadMenuItems();
3623cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
3624cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project            } else {
3625cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // onPageFinished may have already been called but a subframe
3626cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // is still loading and updating the progress. Reset mInLoad
3627cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // and update the menu items.
3628cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                if (!mInLoad) {
3629cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    mInLoad = true;
3630cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    updateInLoadMenuItems();
3631cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedTitle(WebView view, String title) {
3637598c9ccf8641e0e4563bba2fd5613bcb4de766ecPatrick Scott            String url = view.getUrl();
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // here, if url is null, we want to reset the title
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(url, title);
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url == null ||
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url.length() >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3646fce182bff7713a12714018327f6da9500011ab17Leon Scroggins            // See if we can find the current url in our history database and
3647fce182bff7713a12714018327f6da9500011ab17Leon Scroggins            // add the new title to it.
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith("http://www.")) {
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(11);
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (url.startsWith("http://")) {
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(4);
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = "%" + url;
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String [] selArgs = new String[] { url };
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String where = Browser.BookmarkColumns.URL + " LIKE ? AND "
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + Browser.BookmarkColumns.BOOKMARK + " = 0";
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Browser.HISTORY_PROJECTION, where, selArgs, null);
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (c.moveToFirst()) {
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Current implementation of database only has one entry per
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // url.
3664fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    ContentValues map = new ContentValues();
3665fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    map.put(Browser.BookmarkColumns.TITLE, title);
3666fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    mResolver.update(Browser.BOOKMARKS_URI, map,
3667fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                            "_id = " + c.getInt(0), null);
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.close();
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IllegalStateException e) {
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "BrowserActivity onReceived title", e);
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (SQLiteException ex) {
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "onReceivedTitle() caught SQLiteException: ", ex);
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedIcon(WebView view, Bitmap icon) {
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateIcon(view.getUrl(), icon);
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3681092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
3682092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        /**
3683092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * The origin has exceeded it's database quota.
3684092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param url the URL that exceeded the quota
3685092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param databaseIdentifier the identifier of the database on
3686092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         *     which the transaction that caused the quota overflow was run
3687092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param currentQuota the current quota for the origin.
3688092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param quotaUpdater The callback to run when a decision to allow or
3689092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         *     deny quota has been made. Don't forget to call this!
3690092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         */
3691092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        @Override
3692092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        public void onExceededDatabaseQuota(String url,
3693092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch            String databaseIdentifier, long currentQuota,
3694092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch            WebStorage.QuotaUpdater quotaUpdater) {
3695092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch            if(LOGV_ENABLED) {
3696092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                Log.v(LOGTAG,
3697092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      "BrowserActivity received onExceededDatabaseQuota for "
3698092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      + url +
3699092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      ":"
3700092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      + databaseIdentifier +
3701092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      "(current quota: "
3702092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      + currentQuota +
3703092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      ")");
3704092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch            }
370578a98e459323f938e97789a6131beddbebb459ceNicolas Roard            mWebStorageQuotaUpdater = quotaUpdater;
370678a98e459323f938e97789a6131beddbebb459ceNicolas Roard            String DIALOG_PACKAGE = "com.android.browser";
370778a98e459323f938e97789a6131beddbebb459ceNicolas Roard            String DIALOG_CLASS = DIALOG_PACKAGE + ".PermissionDialog";
370878a98e459323f938e97789a6131beddbebb459ceNicolas Roard            Intent intent = new Intent();
370978a98e459323f938e97789a6131beddbebb459ceNicolas Roard            intent.setClassName(DIALOG_PACKAGE, DIALOG_CLASS);
371078a98e459323f938e97789a6131beddbebb459ceNicolas Roard            intent.putExtra(PermissionDialog.PARAM_ORIGIN, url);
371178a98e459323f938e97789a6131beddbebb459ceNicolas Roard            intent.putExtra(PermissionDialog.PARAM_QUOTA, currentQuota);
371278a98e459323f938e97789a6131beddbebb459ceNicolas Roard            startActivityForResult(intent, WEBSTORAGE_QUOTA_DIALOG);
3713092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        }
37147db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch
37157db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        /* Adds a JavaScript error message to the system log.
37167db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param message The error message to report.
37177db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param lineNumber The line number of the error.
37187db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param sourceID The name of the source file that caused the error.
37197db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         */
37207db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        @Override
37217db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        public void addMessageToConsole(String message, int lineNumber, String sourceID) {
37227db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch            Log.w(LOGTAG, "Console: " + message + " (" + sourceID + ":" + lineNumber + ")");
37237db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        }
37247db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
37260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
37290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
37370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
37380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
37390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        || !contentDisposition.regionMatches(true, 0, "attachment", 0, 10)) {
37420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
37450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
37460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (getPackageManager().resolveActivity(intent,
37470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        PackageManager.MATCH_DEFAULT_ONLY) != null) {
37480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // someone knows how to handle this mime type with this scheme, don't download.
37490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
37500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    startActivity(intent);
37510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
37520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (ActivityNotFoundException ex) {
375331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
37540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, "activity not found for " + mimetype
37550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                + " over " + Uri.parse(url).getScheme(), ex);
37560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
37570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Best behavior is to fall back to a download in this case
37580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
37590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
37620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
37630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
37650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
37660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
37670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
37680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
37690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
37700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
37710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
37720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
37730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
37740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
37750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
37770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
37780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
37800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
37810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
37820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
37830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
37840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
37860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
37870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
37880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
37890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
37900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
37910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
37920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
37950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
37960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
37970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
37980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
37990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
38000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
38010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // java.net.URI is a lot stricter than KURL so we have to undo
38040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // KURL's percent-encoding and redo the encoding using java.net.URI.
38050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        URI uri = null;
38060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
38070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Undo the percent-encoding that KURL may have done.
38080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String newUrl = new String(URLUtil.decode(url.getBytes()));
38090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Parse the url into pieces
38100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebAddress w = new WebAddress(newUrl);
38110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String frag = null;
38120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String query = null;
38130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String path = w.mPath;
38140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Break the path into path, query, and fragment
38150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (path.length() > 0) {
38160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Strip the fragment
38170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int idx = path.lastIndexOf('#');
38180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
38190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    frag = path.substring(idx + 1);
38200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
38210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
38220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                idx = path.lastIndexOf('?');
38230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
38240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query = path.substring(idx + 1);
38250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
38260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
38270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
38280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
38290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query, frag);
38300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
38310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
38320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
38330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
38360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
38370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
38380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
38403dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_URI, uri.toString());
38413dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_COOKIE_DATA, cookies);
38423dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_USER_AGENT, userAgent);
38433dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_NOTIFICATION_PACKAGE,
38440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
38453dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_NOTIFICATION_CLASS,
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class.getCanonicalName());
38473dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_VISIBILITY, Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
38483dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_MIME_TYPE, mimetype);
38493dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_FILE_NAME_HINT, filename);
38503dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_DESCRIPTION, uri.getHost());
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
38523dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru            values.put(Downloads.COLUMN_TOTAL_BYTES, contentLength);
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
38560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
38600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getContentResolver().insert(Downloads.CONTENT_URI, values);
38610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            viewDownloads(contentUri);
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        saveLockIcon();
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = LOCK_ICON_UNSECURE;
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (URLUtil.isHttpsUrl(url)) {
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mLockIconType = LOCK_ICON_SECURE;
387731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                      " reset lock icon to " + mLockIconType);
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon.  This method is called when the icon needs to be
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * reset but we do not know whether we are loading a secure or not secure
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * page.
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon() {
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
38930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        saveLockIcon();
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = LOCK_ICON_UNSECURE;
38960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
389731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                " reset lock icon to " + mLockIconType);
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the tab overview is animating or being shown, do not update the
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // lock icon.
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount == 0 && mTabOverview == null) {
391881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            if (CUSTOM_BROWSER_BAR) {
391981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                mTitleBar.setLock(d);
392081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            } else {
392181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, d);
392281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            }
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
39280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showPageInfo(final TabControl.Tab tab,
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
39380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
39400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
39440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
39450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
39470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
39480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
39490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
39500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
39520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
39530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
39550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
39560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
39590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
39600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
39620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
39630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
39660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
39670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
39690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoFromShowSSLCertificateOnError = new Boolean(fromShowSSLCertificateOnError);
39700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
39720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
39730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
39740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
39750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
39760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
39770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
39780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
39790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
39800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
39810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
39820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
39830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
39850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
39860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
39870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
39880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
39890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
39900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
39910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
39920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
39930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
39940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
39950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
39960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
39970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
39980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
39990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
40000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
40020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
40030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
40040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
40050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
40060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
40070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
40080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
40090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
40100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
40110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
40130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
40140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
40150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
40160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
40170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
40180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
40190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
40200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
40210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
40220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
40230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
40240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
40250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
40270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
40280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
40290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
40300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
40310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
40320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
40330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
40340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
40350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
40360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
40370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
40380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
40390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
40400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
40410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
40420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
40450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
40480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
40490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
40500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
40510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificate(final TabControl.Tab tab) {
40530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
40540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
40550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
40560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
40570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
40600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
40620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
40630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
40650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
40660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
40670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
40680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
40700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
40710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
40720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
40730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
40740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
40750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
40760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
40770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
40780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
40790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
40800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
40810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
40830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
40840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
40850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
40860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
40870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
40880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
40890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
40900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
40920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
40930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
40940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
40950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
40990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
41000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
41010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
41020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
41030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
41040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificateOnError(
41050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
41060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
41080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
41090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
41100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
41110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
41140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
41160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
41170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
41190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
41200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
41210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
41220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
41230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
41260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
41270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
41280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
41290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
41300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
41330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
41340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
41350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
41360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
41370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
41400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
41410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
41420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
41430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
41440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
41470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
41480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
41490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
41500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
41510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
41520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
41530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
41540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
41550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
41560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
41570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
41580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
41590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
41600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
41610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
41620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
41640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
41650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
41660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
41670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
41680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
41690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
41700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
41710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
41720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
41740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
41750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
41760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
41780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
41790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
41800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
41810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
41820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
41830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
41840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
41850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
41860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
41870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
41880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
41900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
41910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
41920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
41930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
41940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
41970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
41980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
41990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
42000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
42010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
42020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
42030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
42040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
42050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
42060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
42090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
42110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
42120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
42140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
42150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
42160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
42170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
42180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
42190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
42200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
42210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
42220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
42250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
42260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
42270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
42280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
42290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
42300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
42310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
42320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
42330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
42360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String issuedOn = reformatCertificateDate(
42370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotBefore());
42380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
42390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
42400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
42420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String expiresOn = reformatCertificateDate(
42430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotAfter());
42440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
42450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
42460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
42480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
42510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Re-formats the certificate date (Date.toString()) string to
42520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * a properly localized date string.
42530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
42540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the original certificate date string if fails to localize.
42550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the original string is null, returns an empty string "".
42560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
42570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String reformatCertificateDate(String certificateDate) {
42580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      String reformattedDate = null;
42590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if (certificateDate != null) {
42610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Date date = null;
42620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
42630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = java.text.DateFormat.getInstance().parse(certificateDate);
42640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (ParseException e) {
42650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = null;
42660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
42670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (date != null) {
42690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              reformattedDate =
42700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  DateFormat.getDateFormat(this).format(date);
42710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
42720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
42730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return reformattedDate != null ? reformattedDate :
42750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          (certificateDate != null ? certificateDate : "");
42760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
42790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
42800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
42810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showHttpAuthentication(final HttpAuthHandler handler,
42820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
42830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
42840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
42850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
42860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
42870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
42880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
42890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
42910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
42920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
42950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
42960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
42970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
42980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
43010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
43020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
43030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
43040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
43050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
43060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
43070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
43080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
43090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
43100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
43110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
43120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
43130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
43140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
43150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
43160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
43170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
43180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
43190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
43200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
43210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
43220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
43230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
43240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
43250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
43260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
43270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
43280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
43290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
43300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
43310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
43320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
43330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
43340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
43350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
43360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
43370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
43380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
43390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
43400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
43410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
43420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
43430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
43440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
43450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
43460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
43470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
43480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
43490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
43510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
43520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
43530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
43540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
43550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
43560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
43570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
43580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
43600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
43610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
43620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
43630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
43640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
43650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
43660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
43670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
43680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
43690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
43700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
43710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
43720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
43730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
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     * connectivity manager says net has come or gone... inform the user
43790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
43800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
43810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
43820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
43830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
43840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
43850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
43860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
43870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
43880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
43890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
43900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
43910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
43920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mInLoad && mAlertDialog == null) {
43930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = new AlertDialog.Builder(this)
43940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.loadSuspendedTitle)
43950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.loadSuspended)
43960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
43970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
43980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
43990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
44010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
44020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
44030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
44050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
44070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
44080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
44090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
44100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
44110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
44120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
44130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
44140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
44150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        openTab(data);
44160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
44170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final TabControl.Tab currentTab =
44180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
44190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // If the Window overview is up and we are not in the
44200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // middle of an animation, animate away from it to the
44210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // current tab.
44220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (mTabOverview != null && mAnimationCount == 0) {
442325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            sendAnimateFromOverview(currentTab, false, new UrlData(data),
44248ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                                    null, TAB_OVERVIEW_DELAY, null);
44250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
44260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            dismissSubWindow(currentTab);
44270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (data != null && data.length() != 0) {
44280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                getTopWindow().loadUrl(data);
44290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
44300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
44310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
44320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
44330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
443478a98e459323f938e97789a6131beddbebb459ceNicolas Roard            case WEBSTORAGE_QUOTA_DIALOG:
443578a98e459323f938e97789a6131beddbebb459ceNicolas Roard                long currentQuota = 0;
443678a98e459323f938e97789a6131beddbebb459ceNicolas Roard                if (resultCode == RESULT_OK && intent != null) {
443778a98e459323f938e97789a6131beddbebb459ceNicolas Roard                    currentQuota = intent.getLongExtra(
443878a98e459323f938e97789a6131beddbebb459ceNicolas Roard                        PermissionDialog.PARAM_QUOTA, currentQuota);
443978a98e459323f938e97789a6131beddbebb459ceNicolas Roard                }
444078a98e459323f938e97789a6131beddbebb459ceNicolas Roard                mWebStorageQuotaUpdater.updateQuota(currentQuota);
444178a98e459323f938e97789a6131beddbebb459ceNicolas Roard                break;
44420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
44430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
44440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        getTopWindow().requestFocus();
44460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
44470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
44490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
44500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * menu to see the download window, or when a download changes state. It
44510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * shows the download window ontop of the current window.
44520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
44530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void viewDownloads(Uri downloadRecord) {
44540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
44550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
44560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
44570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, this.DOWNLOAD_PAGE);
44580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
44600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
44620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Handle results from Tab Switcher mTabOverview tool
44630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
44640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class TabListener implements ImageGrid.Listener {
44650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void remove(int position) {
44660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Note: Remove is not enabled if we have only one tab.
446731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (DEBUG && mTabControl.getTabCount() == 1) {
44680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                throw new AssertionError();
44690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
44700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Remember the current tab.
44720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            TabControl.Tab current = mTabControl.getCurrentTab();
44730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab remove = mTabControl.getTab(position);
44740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.removeTab(remove);
44750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we removed the current tab, use the tab at position - 1 if
44760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // possible.
44770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == remove) {
44780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // If the user removes the last tab, act like the New Tab item
44790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // was clicked on.
44800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getTabCount() == 0) {
4481f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    current = mTabControl.createNewTab();
44820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    sendAnimateFromOverview(current, true,
4483f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                            new UrlData(mSettings.getHomePage()), null, TAB_OVERVIEW_DELAY,
44848ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                            null);
44850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
44860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    final int index = position > 0 ? (position - 1) : 0;
44870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current = mTabControl.getTab(index);
44880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
44890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
44900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The tab overview could have been dismissed before this method is
44920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // called.
44930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mTabOverview != null) {
44940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Remove the tab and change the index.
44950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabOverview.remove(position);
44960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabOverview.setCurrentIndex(mTabControl.getTabIndex(current));
44970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
44980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Only the current tab ensures its WebView is non-null. This
45000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // implies that we are reloading the freed tab.
45010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
45020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onClick(int index) {
45040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Change the tab if necessary.
45050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Index equals ImageGrid.CANCEL when pressing back from the tab
45060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // overview.
45070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (index == ImageGrid.CANCEL) {
45080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                index = mTabControl.getCurrentIndex();
45090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // The current index is -1 if the current tab was removed.
45100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (index == -1) {
45110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Take the last tab as a fallback.
45120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    index = mTabControl.getTabCount() - 1;
45130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
45140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // NEW_TAB means that the "New Tab" cell was clicked on.
45170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (index == ImageGrid.NEW_TAB) {
4518f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                openTabAndShow(mSettings.getHomePage(), null, false, null);
45190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
45200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                sendAnimateFromOverview(mTabControl.getTab(index),
45218ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                        false, null, null, 0, null);
45220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // A fake View that draws the WebView's picture with a fast zoom filter.
45270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The View is used in case the tab is freed during the animation because
45280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // of low memory.
45290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static class AnimatingView extends View {
45300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private static final int ZOOM_BITS = Paint.FILTER_BITMAP_FLAG |
45310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Paint.DITHER_FLAG | Paint.SUBPIXEL_TEXT_FLAG;
45320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private static final DrawFilter sZoomFilter =
45330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new PaintFlagsDrawFilter(ZOOM_BITS, Paint.LINEAR_TEXT_FLAG);
45340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final Picture mPicture;
45350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final float   mScale;
45360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final int     mScrollX;
45370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final int     mScrollY;
45380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab  mTab;
45390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AnimatingView(Context ctxt, TabControl.Tab t) {
45410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            super(ctxt);
45420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTab = t;
4543ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott            if (t != null && t.getTopWindow() != null) {
4544ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                // Use the top window in the animation since the tab overview
4545ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                // will display the top window in each cell.
4546ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                final WebView w = t.getTopWindow();
4547ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mPicture = w.capturePicture();
4548ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScale = w.getScale() / w.getWidth();
4549ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScrollX = w.getScrollX();
4550ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScrollY = w.getScrollY();
4551ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott            } else {
4552ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mPicture = null;
4553ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScale = 1.0f;
4554ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScrollX = mScrollY = 0;
4555ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott            }
45560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
45590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        protected void onDraw(Canvas canvas) {
45600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            canvas.save();
45610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            canvas.drawColor(Color.WHITE);
45620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mPicture != null) {
45630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.setDrawFilter(sZoomFilter);
45640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float scale = getWidth() * mScale;
45650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.scale(scale, scale);
45660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.translate(-mScrollX, -mScrollY);
45670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.drawPicture(mPicture);
45680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            canvas.restore();
45700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
45740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  Open the tab picker. This function will always use the current tab in
45750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  its animation.
45760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  @param stay boolean stating whether the tab picker is to remain open
45770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *          (in which case it needs a listener and its menu) or not.
45780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  @param index The index of the tab to show as the selection in the tab
45790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *               overview.
45800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  @param remove If true, the tab at index will be removed after the
45810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                animation completes.
45820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
45830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void tabPicker(final boolean stay, final int index,
45840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final boolean remove) {
45850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabOverview != null) {
45860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
45870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int size = mTabControl.getTabCount();
45900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabListener l = null;
45920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (stay) {
45930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l = mTabListener = new TabListener();
45940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview = new ImageGrid(this, stay, l);
45960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        for (int i = 0; i < size; i++) {
45980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab t = mTabControl.getTab(i);
45990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.populatePickerData(t);
46000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabOverview.add(t);
46010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Tell the tab overview to show the current tab, the tab overview will
46040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // handle the "New Tab" case.
46050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int currentIndex = mTabControl.getCurrentIndex();
46060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview.setCurrentIndex(currentIndex);
46070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the tab overview.
46090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(mTabOverview, COVER_SCREEN_PARAMS);
46100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create a fake AnimatingView to animate the WebView's picture.
46120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab current = mTabControl.getCurrentTab();
46130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final AnimatingView v = new AnimatingView(this, current);
46140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(v, COVER_SCREEN_PARAMS);
46150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        removeTabFromContentView(current);
46160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Pause timers to get the animation smoother.
46170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        current.getWebView().pauseTimers();
46180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Send a message so the tab picker has a chance to layout and get
46200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // positions for all the cells.
46210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessage(mHandler.obtainMessage(ANIMATE_TO_OVERVIEW,
46220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                index, remove ? 1 : 0, v));
46230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setting this will indicate that we are animating to the overview. We
46240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // set it here to prevent another request to animate from coming in
46250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // between now and when ANIMATE_TO_OVERVIEW is handled.
46260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mAnimationCount++;
46270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Always change the title bar to the window overview title while
46280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // animating.
462981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        if (CUSTOM_BROWSER_BAR) {
463081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            mTitleBar.setToTabPicker();
463181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        } else {
463281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, null);
463381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, null);
463481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
463581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                    Window.PROGRESS_VISIBILITY_OFF);
463681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            setTitle(R.string.tab_picker_title);
463781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        }
46380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the menu empty until the animation completes.
46390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = EMPTY_MENU;
46400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
46410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4642e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
46430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
46440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
46450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
46460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
46480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
46490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
46500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
46510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
46520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
46530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
46540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
46550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
46560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
46570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
46580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
46610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
46620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
46630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
46650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
46660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("maxTabsOpen",
46670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabControl.getTabCount() >= TabControl.MAX_TABS);
46680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
46690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
46700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
46710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
46730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
46740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
46760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void loadURL(WebView view, String url) {
46770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
46780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
46790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
46800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mWebViewClient.shouldOverrideUrlLoading(view, url)) {
46810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                view.loadUrl(url);
46820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
46850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void checkMemory() {
46870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
46880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((ActivityManager) getSystemService(ACTIVITY_SERVICE))
46890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .getMemoryInfo(mi);
46900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // FIXME: mi.lowMemory is too aggressive, use (mi.availMem <
46910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // mi.threshold) for now
46920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        if (mi.lowMemory) {
46930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mi.availMem < mi.threshold) {
46940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG, "Browser is freeing memory now because: available="
46950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (mi.availMem / 1024) + "K threshold="
46960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (mi.threshold / 1024) + "K");
46970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.freeMemory();
46980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
47000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
47020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
47030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
47040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
47060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
47070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get window count
47100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    int getWindowCount(){
47120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if(mTabControl != null){
47130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getTabCount();
47140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
47150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return 0;
47160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
47170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4718b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
47190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
47200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
47210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
472225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
47230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
47240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
47250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
47270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
47280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
47290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
47300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
47310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
47320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
47330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
47340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
47350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
47360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
47370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
47390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
47400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
47420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
47430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
47440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
47450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
47460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
4747123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
4748123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
4749123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
4750123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
47510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
47520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
47530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
4755565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
4756565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
4757565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
4758565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
4759565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
4760565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
4761565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
4762565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
4763565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return composeSearchUrl(query);
4764565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
4765565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
4766565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
4767565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
4768565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
47690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
4770565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
47710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
47720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
47730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
47740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Regex.WEB_URL_PATTERN.matcher(inUrl).matches()) {
47750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
47760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
47770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
47800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return composeSearchUrl(inUrl);
47810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
47820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ String composeSearchUrl(String search) {
47840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return URLUtil.composeSearchUrl(search, QuickSearch_G,
47850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                QUERY_PLACE_HOLDER);
47860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
47870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */void setBaseSearchUrl(String url) {
47890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null || url.length() == 0) {
47900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
47910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * get the google search url based on the SIM. Default is US. NOTE:
47920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * This code uses resources to optionally select the search Uri,
47930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * based on the MCC value from the SIM. The default string will most
47940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * likely be fine. It is parameterized to accept info from the
47950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Locale, the language code is the first parameter (%1$s) and the
47960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * country code is the second (%2$s). This code must function in the
47970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * same way as a similar lookup in
47980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * com.android.googlesearch.SuggestionProvider#onCreate(). If you
47990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * change either of these functions, change them both. (The same is
48000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * true for the underlying resource strings, which are stored in
48010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * mcc-specific xml files.)
48020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
48030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Locale l = Locale.getDefault();
4804e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            String language = l.getLanguage();
4805e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            String country = l.getCountry().toLowerCase();
4806e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            // Chinese and Portuguese have two langauge variants.
4807e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            if ("zh".equals(language)) {
4808e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                if ("cn".equals(country)) {
4809e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language = "zh-CN";
4810e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                } else if ("tw".equals(country)) {
4811e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language = "zh-TW";
4812e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                }
4813e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            } else if ("pt".equals(language)) {
4814e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                if ("br".equals(country)) {
4815e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language = "pt-BR";
4816e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                } else if ("pt".equals(country)) {
4817e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language = "pt-PT";
4818e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                }
4819e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            }
48200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            QuickSearch_G = getResources().getString(
4821e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    R.string.google_search_base,
4822e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language,
4823e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    country)
48240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + "client=ms-"
4825dd4f4297c08803b238af28dddb373a1aea06cc1eRamanan Rajeswaran                    + Partner.getString(this.getContentResolver(), Partner.CLIENT_ID)
48268ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    // FIXME, remove this when GEOLOCATION team make their move
48278ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                    + "&action=devloc"
48280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&q=%s";
48290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
48300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            QuickSearch_G = url;
48310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
48320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
48330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int LOCK_ICON_UNSECURE = 0;
48350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int LOCK_ICON_SECURE   = 1;
48360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int LOCK_ICON_MIXED    = 2;
48370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mLockIconType = LOCK_ICON_UNSECURE;
48390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mPrevLockType = LOCK_ICON_UNSECURE;
48400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
48420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
48430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
48440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
48450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ImageGrid       mTabOverview;
48460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
48480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
48490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
48500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
48510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
48520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
48530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
48550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
48560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
48570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
48580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
48600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
48610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mPageStarted;
48630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mActivityInPause = true;
48640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
48660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final KeyTracker mKeyTracker = new KeyTracker(this);
48680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As trackball doesn't send repeat down, we have to track it ourselves
48700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mTrackTrackball;
48710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
48730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
48750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
48760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
48770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
48780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
48790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
48800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
48810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
48820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
48830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
48840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
48850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
48870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
48880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
48890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
48900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
48910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
48920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
48940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
48960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
48970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mGenericFavicon;
48980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
49000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
49010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wait for credentials before loading google.com
49030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ProgressDialog mCredsDlg;
49040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
49060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
49070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
49080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
49090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
49100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
49120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
49130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
49140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mPageInfoView;
49150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
49160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
49170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
49180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Boolean mPageInfoFromShowSSLCertificateOnError;
49190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
49210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
49220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
49230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
49240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
49250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
49260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
49280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
49290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
49300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mSSLCertificateView;
49310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
49330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
49340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
49350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
49360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
49380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
49390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT,
49400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT);
49410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // We may provide UI to customize these
49420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google search from the browser
49430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    static String QuickSearch_G;
49440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
49450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
49460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
49470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
49480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
49490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
49500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
49520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
49540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
49550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
49560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
49570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
49580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
49590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
49600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
49610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
49620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
49630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
49650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabListener mTabListener;
49670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
49690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
49710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
49720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
49740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
497581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins    private TitleBar mTitleBar;
497681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
49770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used during animations to prevent other animations from being triggered.
49780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // A count is used since the animation to and from the Window overview can
49790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // overlap. A count of 0 means no animation where a count of > 0 means
49800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // there are animations in progress.
49810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mAnimationCount;
49820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
49840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
49850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
49860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
49870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
49880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
49890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
49910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
49920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
49930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4994b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
4995b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
49960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
499778a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
499878a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
499978a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
500078a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int WEBSTORAGE_QUOTA_DIALOG    = 4;
50010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // the frenquency of checking whether system memory is low
50030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static int CHECK_MEMORY_INTERVAL = 30000;     // 30 seconds
500425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
500525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
500625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
500725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
500825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
500925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class UrlData {
501025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mUrl;
501125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
501225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
501325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
501425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
501525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
501625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
501725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            return mUrl == null || mUrl.length() == 0;
501825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
501925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
502025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        private void loadIn(WebView webView) {
502125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            webView.loadUrl(mUrl);
502225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
502325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
502425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
502525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
502625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A subclass of UrlData class that can display inlined content using
502725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * {@link WebView#loadDataWithBaseURL(String, String, String, String, String)}.
502825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
502925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class InlinedUrlData extends UrlData {
503025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        InlinedUrlData(String inlined, String mimeType, String encoding, String failUrl) {
503125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            super(failUrl);
503225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mInlined = inlined;
503325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mMimeType = mimeType;
503425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mEncoding = encoding;
503525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
503625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mMimeType;
503725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mInlined;
503825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mEncoding;
503925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
504025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
504125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            return mInlined == null || mInlined.length() == 0 || super.isEmpty();
504225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
504325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
504425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        void loadIn(WebView webView) {
504525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            webView.loadDataWithBaseURL(null, mInlined, mMimeType, mEncoding, mUrl);
504625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
504725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    }
504825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
504925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static final UrlData EMPTY_URL_DATA = new UrlData(null);
50500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
5051