BrowserActivity.java revision b3c02da4553b1a629b16377970fdabae28394c94
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;
32b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport android.content.ContentUris;
330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ContentValues;
340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Context;
350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface;
360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.Intent;
370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.IntentFilter;
380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.ServiceConnection;
390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.DialogInterface.OnCancelListener;
40b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.content.pm.PackageInfo;
410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.PackageManager;
420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.pm.ResolveInfo;
430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.AssetManager;
440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Configuration;
450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.content.res.Resources;
460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.Cursor;
470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.sqlite.SQLiteDatabase;
480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.database.sqlite.SQLiteException;
490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Bitmap;
500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Canvas;
510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Color;
520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.DrawFilter;
530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Paint;
540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.PaintFlagsDrawFilter;
550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.Picture;
560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.BitmapDrawable;
570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.Drawable;
580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.LayerDrawable;
590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.graphics.drawable.PaintDrawable;
600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.hardware.SensorListener;
610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.hardware.SensorManager;
628ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Klobaimport android.location.Location;
638ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Klobaimport android.location.LocationManager;
640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.ConnectivityManager;
650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.Uri;
660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.WebAddress;
670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.EventHandler;
680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslCertificate;
690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.net.http.SslError;
700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.AsyncTask;
710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Bundle;
720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Debug;
730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Environment;
740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Handler;
750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.IBinder;
760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Message;
770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.PowerManager;
780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.Process;
790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.RemoteException;
800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.ServiceManager;
810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemClock;
820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.os.SystemProperties;
830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.preference.PreferenceManager;
840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Browser;
850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Contacts;
860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Downloads;
870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.MediaStore;
888ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Klobaimport android.provider.Settings;
890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.provider.Contacts.Intents.Insert;
900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.IClipboard;
910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.TextUtils;
920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.format.DateFormat;
930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.text.util.Regex;
940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.util.Log;
950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu;
960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Gravity;
970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.KeyEvent;
980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.LayoutInflater;
990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Menu;
1000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuInflater;
1010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem;
1020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.View;
1030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ViewGroup;
1040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.Window;
1050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.WindowManager;
1060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
1070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
1080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.AlphaAnimation;
1090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.Animation;
1100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.AnimationSet;
1110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.DecelerateInterpolator;
1120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.ScaleAnimation;
1130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.view.animation.TranslateAnimation;
1140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieManager;
1150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.CookieSyncManager;
1160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.DownloadListener;
1170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.HttpAuthHandler;
118b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Klobaimport android.webkit.PluginManager;
1190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.SslErrorHandler;
1200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.URLUtil;
1210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebChromeClient;
1220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebHistoryItem;
1230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebIconDatabase;
124092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdochimport android.webkit.WebStorage;
1250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebView;
1260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.webkit.WebViewClient;
1270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.EditText;
1280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.FrameLayout;
1290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.LinearLayout;
1300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.TextView;
1310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport android.widget.Toast;
1320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.BufferedOutputStream;
134b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scrogginsimport java.io.ByteArrayOutputStream;
1350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.File;
1360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.FileInputStream;
1370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.FileOutputStream;
1380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.IOException;
1390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.io.InputStream;
1400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.MalformedURLException;
1410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URI;
1429918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackbornimport java.net.URISyntaxException;
1430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URL;
1440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.net.URLEncoder;
1450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.text.ParseException;
1460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Date;
1470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Enumeration;
1480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.HashMap;
14937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scottimport java.util.LinkedList;
1500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Locale;
1510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.Vector;
1520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Matcher;
1530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.regex.Pattern;
1540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.zip.ZipEntry;
1550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectimport java.util.zip.ZipFile;
1560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Projectpublic class BrowserActivity extends Activity
1580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    implements KeyTracker.OnKeyTracker,
1590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View.OnCreateContextMenuListener,
1600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        DownloadListener {
1610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    /* Define some aliases to make these debugging flags easier to refer to.
16331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
16431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort     */
16531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
16631a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
16731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
16831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort
1690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IGoogleLoginService mGls = null;
1700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ServiceConnection mGlsConnection = null;
1710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SensorManager mSensorManager = null;
1730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17478a98e459323f938e97789a6131beddbebb459ceNicolas Roard    private WebStorage.QuotaUpdater mWebStorageQuotaUpdater = null;
17578a98e459323f938e97789a6131beddbebb459ceNicolas Roard
176565505b1a2c1d3099496af5910760087602e994aSatish Sampath    // These are single-character shortcuts for searching popular sources.
177565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_INVALID = 0;
178565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_SEARCH = 1;
179565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
180565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
181565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
182565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* Whitelisted webpages
1840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static HashSet<String> sWhiteList;
1850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
1860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    static {
1870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList = new HashSet<String>();
1880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("cnn.com/");
1890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("espn.go.com/");
1900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("nytimes.com/");
1910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("engadget.com/");
1920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("yahoo.com/");
1930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("msn.com/");
1940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("amazon.com/");
1950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("consumerist.com/");
1960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        sWhiteList.add("google.com/m/news");
1970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
1980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    */
1990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setupHomePage() {
2010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Runnable getAccount = new Runnable() {
2020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void run() {
2030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Lower priority
2040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
2050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // get the default home page
2060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String homepage = mSettings.getHomePage();
2070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
2090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mGls == null) return;
2100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
211f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                    if (!homepage.startsWith("http://www.google.")) return;
212f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                    if (homepage.indexOf('?') == -1) return;
213f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba
2140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String hostedUser = mGls.getAccount(GoogleLoginServiceConstants.PREFER_HOSTED);
2150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String googleUser = mGls.getAccount(GoogleLoginServiceConstants.REQUIRE_GOOGLE);
2160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // three cases:
2180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser == googleUser
2200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has only a google account
2210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser != googleUser
2230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has a hosted account and a google account
2240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //
2250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //   hostedUser != null, googleUser == null
2260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //      The device has only a hosted account (so far)
2270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // developers might have no accounts at all
2290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (hostedUser == null) return;
2300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (googleUser == null || !hostedUser.equals(googleUser)) {
2320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
233f2c5c1b555904400f4092888ae81b8ed74bfe026Grace Kloba                        homepage = homepage.replace("?", "/a/" + domain + "?");
2340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
2350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (RemoteException ignore) {
2360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Login service died; carry on
2370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (RuntimeException ignore) {
2380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Login service died; carry on
2390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } finally {
2400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    finish(homepage);
2410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            private void finish(final String homepage) {
2450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.post(new Runnable() {
2460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void run() {
2470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mSettings.setHomePage(BrowserActivity.this, homepage);
2480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        resumeAfterCredentials();
2490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // as this is running in a separate thread,
2510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // BrowserActivity's onDestroy() may have been called,
2520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // which also calls unbindService().
2530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (mGlsConnection != null) {
2540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // we no longer need to keep GLS open
2550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            unbindService(mGlsConnection);
2560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mGlsConnection = null;
2570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
2580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } });
2590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } };
2600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final boolean[] done = { false };
2620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open a connection to the Google Login Service.  The first
2640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // time the connection is established, set up the homepage depending on
2650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the account in a background thread.
2660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mGlsConnection = new ServiceConnection() {
2670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void onServiceConnected(ComponentName className, IBinder service) {
2680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mGls = IGoogleLoginService.Stub.asInterface(service);
2690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (done[0] == false) {
2700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    done[0] = true;
2710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Thread account = new Thread(getAccount);
2720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    account.setName("GLSAccount");
2730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    account.start();
2740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
2750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            public void onServiceDisconnected(ComponentName className) {
2770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mGls = null;
2780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        };
2800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bindService(GoogleLoginServiceConstants.SERVICE_INTENT,
2820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mGlsConnection, Context.BIND_AUTO_CREATE);
2830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
2840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
2860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This class is in charge of installing pre-packaged plugins
2870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * from the Browser assets directory to the user's data partition.
2880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Plugins are loaded from the "plugins" directory in the assets;
2890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Anything that is in this directory will be copied over to the
2900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * user data partition in app_plugins.
2910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
2920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class CopyPlugins implements Runnable {
2930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String TAG = "PluginsInstaller";
2940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String ZIP_FILTER = "assets/plugins/";
2950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String APK_PATH = "/system/app/Browser.apk";
2960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String PLUGIN_EXTENSION = ".so";
2970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String TEMPORARY_EXTENSION = "_temp";
2980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String BUILD_INFOS_FILE = "build.prop";
2990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final static String SYSTEM_BUILD_INFOS_FILE = "/system/"
3000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              + BUILD_INFOS_FILE;
3010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int BUFSIZE = 4096;
3020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean mDoOverwrite = false;
3030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String pluginsPath;
3040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Context mContext;
3050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        File pluginsDir;
3060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AssetManager manager;
3070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public CopyPlugins (boolean overwrite, Context context) {
3090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mDoOverwrite = overwrite;
3100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContext = context;
3110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Returned a filtered list of ZipEntry.
3150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We list all the files contained in the zip and
3160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * only returns the ones starting with the ZIP_FILTER
3170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * path.
3180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
3190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param zip the zip file used.
3200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Vector<ZipEntry> pluginsFilesFromZip(ZipFile zip) {
3220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Vector<ZipEntry> list = new Vector<ZipEntry>();
3230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Enumeration entries = zip.entries();
3240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            while (entries.hasMoreElements()) {
3250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ZipEntry entry = (ZipEntry) entries.nextElement();
3260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (entry.getName().startsWith(ZIP_FILTER)) {
3270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  list.add(entry);
3280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return list;
3310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Utility method to copy the content from an inputstream
3350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * to a file output stream.
3360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void copyStreams(InputStream is, FileOutputStream fos) {
3380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BufferedOutputStream os = null;
3390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
3400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                byte data[] = new byte[BUFSIZE];
3410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int count;
3420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                os = new BufferedOutputStream(fos, BUFSIZE);
3430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                while ((count = is.read(data, 0, BUFSIZE)) != -1) {
3440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    os.write(data, 0, count);
3450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                os.flush();
3470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IOException e) {
3480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "Exception while copying: " + e);
3490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } finally {
3500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              try {
3510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (os != null) {
3520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    os.close();
3530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
3540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              } catch (IOException e2) {
3550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "Exception while closing the stream: " + e2);
3560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
3570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Returns a string containing the contents of a file
3620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
3630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param file the target file
3640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String contentsOfFile(File file) {
3660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          String ret = null;
3670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          FileInputStream is = null;
3680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
3690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            byte[] buffer = new byte[BUFSIZE];
3700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int count;
3710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            is = new FileInputStream(file);
3720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            StringBuffer out = new StringBuffer();
3730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            while ((count = is.read(buffer, 0, BUFSIZE)) != -1) {
3750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              out.append(new String(buffer, 0, count));
3760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ret = out.toString();
3780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (IOException e) {
3790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exception getting contents of file " + e);
3800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } finally {
3810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (is != null) {
3820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              try {
3830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                is.close();
3840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              } catch (IOException e2) {
3850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "Exception while closing the file: " + e2);
3860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
3870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
3890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          return ret;
3900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
3930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Utility method to initialize the user data plugins path.
3940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
3950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void initPluginsPath() {
3960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BrowserSettings s = BrowserSettings.getInstance();
3970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            pluginsPath = s.getPluginsPath();
3980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (pluginsPath == null) {
3990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                s.loadFromDb(mContext);
4000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                pluginsPath = s.getPluginsPath();
4010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
40231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
4030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(TAG, "Plugin path: " + pluginsPath);
4040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Utility method to delete a file or a directory
4090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
4100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param file the File to delete
4110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void deleteFile(File file) {
4130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File[] files = file.listFiles();
4140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((files != null) && files.length > 0) {
4150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              for (int i=0; i< files.length; i++) {
4160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                deleteFile(files[i]);
4170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
4180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!file.delete()) {
4200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              Log.e(TAG, file.getPath() + " could not get deleted");
4210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Clean the content of the plugins directory.
4260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We delete the directory, then recreate it.
4270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void cleanPluginsDirectory() {
42931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort          if (LOGV_ENABLED) {
4300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(TAG, "delete plugins directory: " + pluginsPath);
4310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
4320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          File pluginsDirectory = new File(pluginsPath);
4330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          deleteFile(pluginsDirectory);
4340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          pluginsDirectory.mkdir();
4350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Copy the SYSTEM_BUILD_INFOS_FILE file containing the
4400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * informations about the system build to the
4410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * BUILD_INFOS_FILE in the plugins directory.
4420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void copyBuildInfos() {
4440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
44531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
4460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              Log.v(TAG, "Copy build infos to the plugins directory");
4470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
4490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE);
4500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyStreams(new FileInputStream(buildInfoFile),
4510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new FileOutputStream(buildInfoPlugins));
4520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (IOException e) {
4530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exception while copying the build infos: " + e);
4540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
4550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
4580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Returns true if the current system is newer than the
4590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * system that installed the plugins.
4600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We determinate this by checking the build number of the system.
4610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
4620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * At the end of the plugins copy operation, we copy the
4630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * SYSTEM_BUILD_INFOS_FILE to the BUILD_INFOS_FILE.
4640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We then just have to load both and compare them -- if they
4650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * are different the current system is newer.
4660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
4670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Loading and comparing the strings should be faster than
4680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * creating a hash, the files being rather small. Extracting the
4690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * version number would require some parsing which may be more
4700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * brittle.
4710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
4720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean newSystemImage() {
4730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
4740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
4750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE);
4760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!buildInfoPlugins.exists()) {
47731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort              if (LOGV_ENABLED) {
4780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(TAG, "build.prop in plugins directory " + pluginsPath
4790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  + " does not exist, therefore it's a new system image");
4800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
4810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              return true;
4820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
4830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              String buildInfo = contentsOfFile(buildInfoFile);
4840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              String buildInfoPlugin = contentsOfFile(buildInfoPlugins);
4850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              if (buildInfo == null || buildInfoPlugin == null
4860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  || buildInfo.compareTo(buildInfoPlugin) != 0) {
48731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                if (LOGV_ENABLED) {
4880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  Log.v(TAG, "build.prop are different, "
4890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + " therefore it's a new system image");
4900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
4910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
4920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
4930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
4940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (Exception e) {
4950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exc in newSystemImage(): " + e);
4960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
4970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          return false;
4980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
4990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
5010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Check if the version of the plugins contained in the
5020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Browser assets is the same as the version of the plugins
5030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * in the plugins directory.
5040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * We simply iterate on every file in the assets/plugins
5050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * and return false if a file listed in the assets does
5060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * not exist in the plugins directory.
5070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
5080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private boolean checkIsDifferentVersions() {
5090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
5100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ZipFile zip = new ZipFile(APK_PATH);
5110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Vector<ZipEntry> files = pluginsFilesFromZip(zip);
5120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int zipFilterLength = ZIP_FILTER.length();
5130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Enumeration entries = files.elements();
5150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            while (entries.hasMoreElements()) {
5160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              ZipEntry entry = (ZipEntry) entries.nextElement();
5170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              String path = entry.getName().substring(zipFilterLength);
5180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              File outputFile = new File(pluginsPath, path);
5190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              if (!outputFile.exists()) {
52031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                if (LOGV_ENABLED) {
5210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  Log.v(TAG, "checkIsDifferentVersions(): extracted file "
5220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + path + " does not exist, we have a different version");
5230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
5250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              }
5260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
5270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (IOException e) {
5280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(TAG, "Exception in checkDifferentVersions(): " + e);
5290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
5300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          return false;
5310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
5320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
5340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Copy every files from the assets/plugins directory
5350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * to the app_plugins directory in the data partition.
5360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Once copied, we copy over the SYSTEM_BUILD_INFOS file
5370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * in the plugins directory.
5380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
5390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * NOTE: we directly access the content from the Browser
5400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * package (it's a zip file) and do not use AssetManager
5410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * as there is a limit of 1Mb (see Asset.h)
5420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
5430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void run() {
5440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Lower the priority
5450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
5470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (pluginsPath == null) {
5480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Log.e(TAG, "No plugins path found!");
5490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
5500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ZipFile zip = new ZipFile(APK_PATH);
5530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Vector<ZipEntry> files = pluginsFilesFromZip(zip);
5540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Vector<File> plugins = new Vector<File>();
5550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int zipFilterLength = ZIP_FILTER.length();
5560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Enumeration entries = files.elements();
5580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                while (entries.hasMoreElements()) {
5590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ZipEntry entry = (ZipEntry) entries.nextElement();
5600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String path = entry.getName().substring(zipFilterLength);
5610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    File outputFile = new File(pluginsPath, path);
5620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    outputFile.getParentFile().mkdirs();
5630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (outputFile.exists() && !mDoOverwrite) {
56531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
5660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(TAG, path + " already extracted.");
5670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
5680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
5690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (path.endsWith(PLUGIN_EXTENSION)) {
5700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // We rename plugins to be sure a half-copied
5710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // plugin is not loaded by the browser.
5720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            plugins.add(outputFile);
5730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            outputFile = new File(pluginsPath,
5740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                path + TEMPORARY_EXTENSION);
5750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
5760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        FileOutputStream fos = new FileOutputStream(outputFile);
57731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
5780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(TAG, "copy " + entry + " to "
5790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                + pluginsPath + "/" + path);
5800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
5810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        copyStreams(zip.getInputStream(entry), fos);
5820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
5830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // We now rename the .so we copied, once all their resources
5860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // are safely copied over to the user data partition.
5870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Enumeration elems = plugins.elements();
5880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                while (elems.hasMoreElements()) {
5890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    File renamedFile = (File) elems.nextElement();
5900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    File sourceFile = new File(renamedFile.getPath()
5910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + TEMPORARY_EXTENSION);
59231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGV_ENABLED) {
5930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.v(TAG, "rename " + sourceFile.getPath()
5940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " to " + renamedFile.getPath());
5950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
5960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    sourceFile.renameTo(renamedFile);
5970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
5980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                copyBuildInfos();
6000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IOException e) {
6010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(TAG, "IO Exception: " + e);
6020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
6030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
6050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
6070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Copy the content of assets/plugins/ to the app_plugins directory
6080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * in the data partition.
6090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
6100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called every time the browser is started.
6110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * We first check if the system image is newer than the one that
6120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * copied the plugins (if there's plugins in the data partition).
6130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If this is the case, we then check if the versions are different.
6140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If they are different, we clean the plugins directory in the
6150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * data partition, then start a thread to copy the plugins while
6160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the browser continue to load.
6170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
6180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param overwrite if true overwrite the files even if they are
6190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * already present (to let the user "reset" the plugins if needed).
6200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
6210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copyPlugins(boolean overwrite) {
6220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        CopyPlugins copyPluginsFromAssets = new CopyPlugins(overwrite, this);
6230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        copyPluginsFromAssets.initPluginsPath();
6240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (copyPluginsFromAssets.newSystemImage())  {
6250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (copyPluginsFromAssets.checkIsDifferentVersions()) {
6260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyPluginsFromAssets.cleanPluginsDirectory();
6270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Thread copyplugins = new Thread(copyPluginsFromAssets);
6280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyplugins.setName("CopyPlugins");
6290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyplugins.start();
6300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
6310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
6330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class ClearThumbnails extends AsyncTask<File, Void, Void> {
6350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
6360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Void doInBackground(File... files) {
6370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (files != null) {
6380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                for (File f : files) {
6390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    f.delete();
6400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
6410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
6420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
6430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
6450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
64681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins    // Flag to enable the touchable browser bar with buttons
64781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins    private final boolean CUSTOM_BROWSER_BAR = true;
64881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
6490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public void onCreate(Bundle icicle) {
65031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
6510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, this + " onStart");
6520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
6530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreate(icicle);
65481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        if (CUSTOM_BROWSER_BAR) {
65581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
65681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        } else {
65781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
65881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_RIGHT_ICON);
65981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_PROGRESS);
66081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
66181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        }
6620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // test the browser in OpenGL
6630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // requestWindowFeature(Window.FEATURE_OPENGL);
6640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
6660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mResolver = getContentResolver();
6680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setBaseSearchUrl(PreferenceManager.getDefaultSharedPreferences(this)
6700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .getString("search_url", ""));
6710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
6730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // start MASF proxy service
6740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
6750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
6760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
6770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //    (new ComponentName(
6780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
6790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
6800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //startService(proxyServiceIntent, null);
6810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
6820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSecLockIcon = Resources.getSystem().getDrawable(
6830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_secure);
6840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMixLockIcon = Resources.getSystem().getDrawable(
6850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                android.R.drawable.ic_partial_secure);
6860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mGenericFavicon = getResources().getDrawable(
6870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.drawable.app_web_browser_sm);
6880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
68981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        FrameLayout frameLayout = (FrameLayout) getWindow().getDecorView()
69081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                .findViewById(com.android.internal.R.id.content);
69181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        if (CUSTOM_BROWSER_BAR) {
692adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // This FrameLayout will hold the custom FrameLayout and a LinearLayout
693adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // that contains the title bar and a FrameLayout, which
69481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            // holds everything else.
695adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            FrameLayout browserFrameLayout = (FrameLayout) LayoutInflater.from(this)
696e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins                    .inflate(R.layout.custom_screen, null);
697adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mTitleBar = (TitleBar) browserFrameLayout.findViewById(R.id.title_bar);
698e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins            mTitleBar.setBrowserActivity(this);
699adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mContentView = (FrameLayout) browserFrameLayout.findViewById(
700e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins                    R.id.main_content);
701adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer = (FrameLayout) browserFrameLayout
702adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                    .findViewById(R.id.fullscreen_custom_content);
703adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            frameLayout.addView(browserFrameLayout, COVER_SCREEN_PARAMS);
70481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        } else {
705adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer = new FrameLayout(this);
70678f757042015063d016b15893a650c44fdfd4e5cAndrei Popescu            mCustomViewContainer.setBackgroundColor(Color.BLACK);
707adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mContentView = new FrameLayout(this);
708adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            frameLayout.addView(mCustomViewContainer, COVER_SCREEN_PARAMS);
709adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            frameLayout.addView(mContentView, COVER_SCREEN_PARAMS);
71081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        }
7110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create the tab control and our initial tab
7130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl = new TabControl(this);
7140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Open the icon database and retain all the bookmark urls for favicons
7160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        retainIconsOnStartup();
7170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Keep a settings instance handy.
7190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings = BrowserSettings.getInstance();
7200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setTabControl(mTabControl);
7210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.loadFromDb(this);
7220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
7240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
7250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
726565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // If this was a web search request, pass it on to the default web search provider.
727565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (handleWebSearchIntent(getIntent())) {
728565505b1a2c1d3099496af5910760087602e994aSatish Sampath            moveTaskToBack(true);
729565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return;
730565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
731565505b1a2c1d3099496af5910760087602e994aSatish Sampath
7320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mTabControl.restoreState(icicle)) {
7330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // clear up the thumbnail directory if we can't restore the state as
7340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // none of the files in the directory are referenced any more.
7350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new ClearThumbnails().execute(
7360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getThumbnailDir().listFiles());
7370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Intent intent = getIntent();
7380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Bundle extra = intent.getExtras();
7390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create an initial tab.
7400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the intent is ACTION_VIEW and data is not null, the Browser is
7410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // invoked to view the content by another application. In this case,
7420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the tab will be close when exit.
74325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
74425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
7450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab t = mTabControl.createNewTab(
7460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent.ACTION_VIEW.equals(intent.getAction()) &&
747f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    intent.getData() != null,
74825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
7490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(t);
7500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This is one of the only places we call attachTabToContentView
7510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // without animating from the tab picker.
7520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(t);
7530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView webView = t.getWebView();
7540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (extra != null) {
7550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
7560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (scale > 0 && scale <= 1000) {
7570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.setInitialScale(scale);
7580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we are not restoring from an icicle, then there is a high
7610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // likely hood this is the first run. So, check to see if the
7620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // homepage needs to be configured and copy any plugins from our
7630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // asset directory to the data partition.
7640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if ((extra == null || !extra.getBoolean("testing"))
7650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    && !mSettings.isLoginInitialized()) {
7660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                setupHomePage();
7670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copyPlugins(true);
7690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
77025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
7710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mSettings.isLoginInitialized()) {
7720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    webView.loadUrl(mSettings.getHomePage());
7730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
7740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    waitForCredentials();
7750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
7760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
77760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                urlData.setPostData(getLocationData(intent));
77825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData.loadIn(webView);
7790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
7800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
7810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TabControl.restoreState() will create a new tab even if
7820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // restoring the state fails. Attach it to the view here since we
7830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not animating from the tab picker.
7840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(mTabControl.getCurrentTab());
7850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
786b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        // Read JavaScript flags if it exists.
787b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        String jsFlags = mSettings.getJsFlags();
788b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        if (jsFlags.trim().length() != 0) {
789b3c02da4553b1a629b16377970fdabae28394c94Feng Qian            mTabControl.getCurrentWebView().setJsFlags(jsFlags);
790b3c02da4553b1a629b16377970fdabae28394c94Feng Qian        }
7910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
7920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /* enables registration for changes in network status from
7930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project           http stack */
7940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mNetworkStateChangedFilter = new IntentFilter();
7950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mNetworkStateChangedFilter.addAction(
7960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ConnectivityManager.CONNECTIVITY_ACTION);
7970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mNetworkStateIntentReceiver = new BroadcastReceiver() {
7980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                @Override
7990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                public void onReceive(Context context, Intent intent) {
8000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (intent.getAction().equals(
8010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            ConnectivityManager.CONNECTIVITY_ACTION)) {
8020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        boolean down = intent.getBooleanExtra(
8030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
8040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        onNetworkToggle(!down);
8050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
8060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
8070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            };
808b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
809b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
810b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
811b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        filter.addDataScheme("package");
812b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        mPackageInstallationReceiver = new BroadcastReceiver() {
813b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba            @Override
814b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba            public void onReceive(Context context, Intent intent) {
815b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                final String action = intent.getAction();
816b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                final String packageName = intent.getData()
817b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        .getSchemeSpecificPart();
818b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                final boolean replacing = intent.getBooleanExtra(
819b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        Intent.EXTRA_REPLACING, false);
820b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
821b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    // if it is replacing, refreshPlugins() when adding
822b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    return;
823b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                }
824b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                PackageManager pm = BrowserActivity.this.getPackageManager();
825b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                PackageInfo pkgInfo = null;
826b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                try {
827b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    pkgInfo = pm.getPackageInfo(packageName,
828b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                            PackageManager.GET_PERMISSIONS);
829b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                } catch (PackageManager.NameNotFoundException e) {
830b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    return;
831b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                }
832b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                if (pkgInfo != null) {
833b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    String permissions[] = pkgInfo.requestedPermissions;
834b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    if (permissions == null) {
835b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        return;
836b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    }
837b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    boolean permissionOk = false;
838b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    for (String permit : permissions) {
839b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        if (PluginManager.PLUGIN_PERMISSION.equals(permit)) {
840b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                            permissionOk = true;
841b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                            break;
842b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        }
843b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    }
844b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    if (permissionOk) {
845b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                        PluginManager.getInstance(BrowserActivity.this)
846b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                                .refreshPlugins(
847b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                                        Intent.ACTION_PACKAGE_ADDED
848b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                                                .equals(action));
849b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                    }
850b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba                }
851b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba            }
852b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        };
853b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        registerReceiver(mPackageInstallationReceiver, filter);
8540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
8550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
8560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
8570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onNewIntent(Intent intent) {
8580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
8590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // When a tab is closed on exit, the current tab index is set to -1.
8600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Reset before proceed as Browser requires the current tab to be set.
8610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
8620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Try to reset the tab in case the index was incorrect.
8630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current = mTabControl.getTab(0);
8640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == null) {
8650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No tabs at all so just ignore this intent.
8660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
8670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
8680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
8690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            attachTabToContentView(current);
8700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(current.getWebView());
8710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final String action = intent.getAction();
8730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final int flags = intent.getFlags();
8740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_MAIN.equals(action) ||
8750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
8760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just resume the browser
8770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
8780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
8790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (Intent.ACTION_VIEW.equals(action)
8800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_SEARCH.equals(action)
8810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
8820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || Intent.ACTION_WEB_SEARCH.equals(action)) {
883565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // If this was a search request (e.g. search query directly typed into the address bar),
884565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // pass it on to the default web search provider.
885565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (handleWebSearchIntent(intent)) {
886565505b1a2c1d3099496af5910760087602e994aSatish Sampath                return;
887565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
888565505b1a2c1d3099496af5910760087602e994aSatish Sampath
88925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            UrlData urlData = getUrlDataFromIntent(intent);
89025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            if (urlData.isEmpty()) {
89125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData = new UrlData(mSettings.getHomePage());
8920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
89360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            urlData.setPostData(getLocationData(intent));
89425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
8950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action) &&
8960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
897f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                final String appId =
898f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        intent.getStringExtra(Browser.EXTRA_APPLICATION_ID);
899f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                final TabControl.Tab appTab = mTabControl.getTabFromId(appId);
900f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                if (appTab != null) {
901f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    Log.i(LOGTAG, "Reusing tab for " + appId);
902f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Dismiss the subwindow if applicable.
903f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    dismissSubWindow(appTab);
904f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Since we might kill the WebView, remove it from the
905f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // content view first.
906f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    removeTabFromContentView(appTab);
907f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // Recreate the main WebView after destroying the old one.
908f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // If the WebView has the same original url and is on that
909f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    // page, it can be reused.
910f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    boolean needsLoad =
91125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            mTabControl.recreateWebView(appTab, urlData.mUrl);
91225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
913f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    if (current != appTab) {
91425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                        showTab(appTab, needsLoad ? urlData : EMPTY_URL_DATA);
915f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    } else {
916f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        if (mTabOverview != null && mAnimationCount == 0) {
917f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            sendAnimateFromOverview(appTab, false,
918ec7eb37292836652e096b5804877e803e2505136Grace Kloba                                    needsLoad ? urlData : EMPTY_URL_DATA,
9198ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                                    TAB_OVERVIEW_DELAY, null);
920f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        } else {
921f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            // If the tab was the current tab, we have to attach
922f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            // it to the view system again.
923f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            attachTabToContentView(appTab);
924f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            if (needsLoad) {
92525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                                urlData.loadIn(appTab.getWebView());
926f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                            }
927f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                        }
928f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    }
929f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    return;
930f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                }
9310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url will be
9320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // opened in a new tab unless we have reached MAX_TABS. Then the
9330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // url will be opened in the current tab. If a new tab is
9340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // created, it will have "true" for exit on close.
93525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                openTabAndShow(urlData, null, true, appId);
9360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
93725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("about:debug".equals(urlData.mUrl)) {
9380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSettings.toggleDebugSettings();
9390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
9400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
9410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // If the Window overview is up and we are not in the midst of
9420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // an animation, animate away from the Window overview.
9430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabOverview != null && mAnimationCount == 0) {
94425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    sendAnimateFromOverview(current, false, urlData,
9450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            TAB_OVERVIEW_DELAY, null);
9460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
9470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Get rid of the subwindow if it exists
9480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
94925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    urlData.loadIn(current.getWebView());
9500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
9510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
9520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
9530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
9540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
955565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private int parseUrlShortcut(String url) {
956565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url == null) return SHORTCUT_INVALID;
957565505b1a2c1d3099496af5910760087602e994aSatish Sampath
958565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // FIXME: quick search, need to be customized by setting
959565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (url.length() > 2 && url.charAt(1) == ' ') {
960565505b1a2c1d3099496af5910760087602e994aSatish Sampath            switch (url.charAt(0)) {
961565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'g': return SHORTCUT_GOOGLE_SEARCH;
962565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
963565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'd': return SHORTCUT_DICTIONARY_SEARCH;
964565505b1a2c1d3099496af5910760087602e994aSatish Sampath            case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
965565505b1a2c1d3099496af5910760087602e994aSatish Sampath            }
966565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
967565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return SHORTCUT_INVALID;
968565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
969565505b1a2c1d3099496af5910760087602e994aSatish Sampath
970565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
971565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given intent's data
972565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * are identified as plain search terms and not URLs/shortcuts.
973565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the intent was handled and web search activity was launched, false if not.
974565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
975565505b1a2c1d3099496af5910760087602e994aSatish Sampath    private boolean handleWebSearchIntent(Intent intent) {
976565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (intent == null) return false;
977565505b1a2c1d3099496af5910760087602e994aSatish Sampath
978565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = null;
979565505b1a2c1d3099496af5910760087602e994aSatish Sampath        final String action = intent.getAction();
980565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Intent.ACTION_VIEW.equals(action)) {
981565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getData().toString();
982565505b1a2c1d3099496af5910760087602e994aSatish Sampath        } else if (Intent.ACTION_SEARCH.equals(action)
983565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
984565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || Intent.ACTION_WEB_SEARCH.equals(action)) {
985565505b1a2c1d3099496af5910760087602e994aSatish Sampath            url = intent.getStringExtra(SearchManager.QUERY);
986565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
98715e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA));
988565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
989565505b1a2c1d3099496af5910760087602e994aSatish Sampath
990565505b1a2c1d3099496af5910760087602e994aSatish Sampath    /**
991565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * Launches the default web search activity with the query parameters if the given url string
992565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * was identified as plain search terms and not URL/shortcut.
993565505b1a2c1d3099496af5910760087602e994aSatish Sampath     * @return true if the request was handled and web search activity was launched, false if not.
994565505b1a2c1d3099496af5910760087602e994aSatish Sampath     */
99515e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath    private boolean handleWebSearchRequest(String inUrl, Bundle appData) {
996565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (inUrl == null) return false;
997565505b1a2c1d3099496af5910760087602e994aSatish Sampath
998565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // In general, we shouldn't modify URL from Intent.
999565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // But currently, we get the user-typed URL from search box as well.
1000565505b1a2c1d3099496af5910760087602e994aSatish Sampath        String url = fixUrl(inUrl).trim();
1001565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1002565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // URLs and site specific search shortcuts are handled by the regular flow of control, so
1003565505b1a2c1d3099496af5910760087602e994aSatish Sampath        // return early.
1004565505b1a2c1d3099496af5910760087602e994aSatish Sampath        if (Regex.WEB_URL_PATTERN.matcher(url).matches()
1005bc5b9f358a2b75bf3a104b9f5cd477ad2f6f740fSatish Sampath                || ACCEPTED_URI_SCHEMA.matcher(url).matches()
1006565505b1a2c1d3099496af5910760087602e994aSatish Sampath                || parseUrlShortcut(url) != SHORTCUT_INVALID) {
1007565505b1a2c1d3099496af5910760087602e994aSatish Sampath            return false;
1008565505b1a2c1d3099496af5910760087602e994aSatish Sampath        }
1009565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1010565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.updateVisitedHistory(mResolver, url, false);
1011565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Browser.addSearchUrl(mResolver, url);
1012565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1013565505b1a2c1d3099496af5910760087602e994aSatish Sampath        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
1014565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.addCategory(Intent.CATEGORY_DEFAULT);
1015565505b1a2c1d3099496af5910760087602e994aSatish Sampath        intent.putExtra(SearchManager.QUERY, url);
101615e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        if (appData != null) {
101715e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath            intent.putExtra(SearchManager.APP_DATA, appData);
101815e9f2dc92cf1621f95071b3c740f46079aa0f3bSatish Sampath        }
1019565505b1a2c1d3099496af5910760087602e994aSatish Sampath        startActivity(intent);
1020565505b1a2c1d3099496af5910760087602e994aSatish Sampath
1021565505b1a2c1d3099496af5910760087602e994aSatish Sampath        return true;
1022565505b1a2c1d3099496af5910760087602e994aSatish Sampath    }
1023565505b1a2c1d3099496af5910760087602e994aSatish Sampath
102425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private UrlData getUrlDataFromIntent(Intent intent) {
10250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
10260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (intent != null) {
10270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String action = intent.getAction();
10280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Intent.ACTION_VIEW.equals(action)) {
10290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = smartUrlFilter(intent.getData());
10300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null && url.startsWith("content:")) {
10310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    /* Append mimetype so webview knows how to display */
10320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String mimeType = intent.resolveType(getContentResolver());
10330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mimeType != null) {
10340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url += "?" + mimeType;
10350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
10360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
103725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if ("inline:".equals(url)) {
103825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    return new InlinedUrlData(
103925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_CONTENT),
104025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getType(),
104125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_ENCODING),
104225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                            intent.getStringExtra(Browser.EXTRA_INLINE_FAILURL));
104325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                }
10440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (Intent.ACTION_SEARCH.equals(action)
10450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
10460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
10470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = intent.getStringExtra(SearchManager.QUERY);
10480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url != null) {
10490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastEnteredUrl = url;
10500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Don't add Urls, just search terms.
10510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Urls will get added when the page is loaded.
10520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!Regex.WEB_URL_PATTERN.matcher(url).matches()) {
10530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Browser.updateVisitedHistory(mResolver, url, false);
10540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
10550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // In general, we shouldn't modify URL from Intent.
10560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // But currently, we get the user-typed URL from search box as well.
10570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = fixUrl(url);
10580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url = smartUrlFilter(url);
10590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
10600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url.contains(searchSource)) {
10610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String source = null;
10620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
10630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (appData != null) {
10640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = appData.getString(SearchManager.SOURCE);
10650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
10660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (TextUtils.isEmpty(source)) {
10670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
10680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
10690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        url = url.replace(searchSource, "&source=android-"+source+"&");
10700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
10710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
10720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
10730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
107425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        return new UrlData(url);
10750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
10760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
10778ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba    byte[] getLocationData(Intent intent) {
10788ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba        byte[] postData = null;
10798ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba        if (intent != null) {
10808ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            final String action = intent.getAction();
108160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            if (Intent.ACTION_VIEW.equals(action)
108260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                    && intent.getBooleanExtra(Browser.EXTRA_APPEND_LOCATION,
108360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                            false)) {
108460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                ContentResolver cr = getContentResolver();
10852595f146fecd3828231c6611362cce65acd9afb6Grace Kloba                int use = Settings.Secure.getInt(cr,
10862595f146fecd3828231c6611362cce65acd9afb6Grace Kloba                        Settings.Secure.USE_LOCATION_FOR_SERVICES, -1);
108760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                if (use == -1) {
10882595f146fecd3828231c6611362cce65acd9afb6Grace Kloba                    // bring up the consent dialog if it is undefined. And we
10892595f146fecd3828231c6611362cce65acd9afb6Grace Kloba                    // will not send the location info for this query.
10902595f146fecd3828231c6611362cce65acd9afb6Grace Kloba                    Intent consent = new Intent(
10912595f146fecd3828231c6611362cce65acd9afb6Grace Kloba                            Settings.ACTION_SECURITY_SETTINGS);
10922595f146fecd3828231c6611362cce65acd9afb6Grace Kloba                    consent.putExtra("SHOW_USE_LOCATION", true);
10932595f146fecd3828231c6611362cce65acd9afb6Grace Kloba                    startActivity(consent);
109460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                } else if (use == 1
109560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                        && Settings.Secure.isLocationProviderEnabled(cr,
109660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                                LocationManager.NETWORK_PROVIDER)) {
109760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                    Location location = ((LocationManager) getSystemService(
109860e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                            Context.LOCATION_SERVICE)).getLastKnownLocation(
109960e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                                    LocationManager.NETWORK_PROVIDER);
110060e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                    if (location != null) {
110160e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                        StringBuilder str = new StringBuilder(
110260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                                "action=devloc&sll=");
110360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                        str.append(location.getLatitude()).append(',').append(
110460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                                location.getLongitude());
110560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                        postData = str.toString().getBytes();
110660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                    }
11078ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba                }
11088ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba            }
11098ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba        }
11108ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba        return postData;
11118ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba    }
11128ca2c797c8d11168b4055b6ec6b75d87bb8c4e45Grace Kloba
11130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ static String fixUrl(String inUrl) {
11140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
11150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
11160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUrl.startsWith("http:") ||
11170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl.startsWith("https:")) {
11180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
11190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inUrl = inUrl.replaceFirst("/", "//");
11200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else inUrl = inUrl.replaceFirst(":", "://");
11210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
11220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return inUrl;
11230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
11240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
11260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Looking for the pattern like this
11270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
11280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *          *
11290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *         * *
11300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *      ***   *     *******
11310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *             *   *
11320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *              * *
11330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *               *
11340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
11350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final SensorListener mSensorListener = new SensorListener() {
11360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private long mLastGestureTime;
11370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrev = new float[3];
11380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mPrevDiff = new float[3];
11390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mDiff = new float[3];
11400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private float[] mRevertDiff = new float[3];
11410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onSensorChanged(int sensor, float[] values) {
11430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean show = false;
11440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            float[] diff = new float[3];
11450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            for (int i = 0; i < 3; i++) {
11470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                diff[i] = values[i] - mPrev[i];
11480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Math.abs(diff[i]) > 1) {
11490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    show = true;
11500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
11510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((diff[i] > 1.0 && mDiff[i] < 0.2)
11520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        || (diff[i] < -1.0 && mDiff[i] > -0.2)) {
11530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // start track when there is a big move, or revert
11540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mRevertDiff[i] = mDiff[i];
11550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = 0;
11560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else if (diff[i] > -0.2 && diff[i] < 0.2) {
11570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // reset when it is flat
11580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mDiff[i] = mRevertDiff[i]  = 0;
11590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
11600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mDiff[i] += diff[i];
11610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrevDiff[i] = diff[i];
11620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPrev[i] = values[i];
11630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
11660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only shows if we think the delta is big enough, in an attempt
11670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // to detect "serious" moves left/right or up/down
11680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "sensorChanged " + sensor + " ("
11690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + values[0] + ", " + values[1] + ", " + values[2] + ")"
11700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + " diff(" + diff[0] + " " + diff[1] + " " + diff[2]
11710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + ")");
11720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.d("BrowserSensorHack", "      mDiff(" + mDiff[0] + " "
11730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mDiff[1] + " " + mDiff[2] + ")" + " mRevertDiff("
11740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[0] + " " + mRevertDiff[1] + " "
11750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + mRevertDiff[2] + ")");
11760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
11770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            long now = android.os.SystemClock.uptimeMillis();
11790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (now - mLastGestureTime > 1000) {
11800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mLastGestureTime = 0;
11810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float y = mDiff[1];
11830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float z = mDiff[2];
11840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ay = Math.abs(y);
11850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float az = Math.abs(z);
11860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ry = mRevertDiff[1];
11870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float rz = mRevertDiff[2];
11880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float ary = Math.abs(ry);
11890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float arz = Math.abs(rz);
11900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestY = ay > 2.5f && ary > 1.0f && ay > ary;
11910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean gestZ = az > 3.5f && arz > 1.0f && az > arz;
11920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ((gestY || gestZ) && !(gestY && gestZ)) {
11940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = mTabControl.getCurrentWebView();
11950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
11960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (view != null) {
11970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (gestZ) {
11980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (z < 0) {
11990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomOut();
12000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            } else {
12010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                view.zoomIn();
12020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
12030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
12040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            view.flingScroll(0, Math.round(y * 100));
12050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
12060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
12070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mLastGestureTime = now;
12080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
12090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onAccuracyChanged(int sensor, int accuracy) {
12130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // TODO Auto-generated method stub
12140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
12170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onResume() {
12190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onResume();
122031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
12210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
12220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mActivityInPause) {
12250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already resumed.");
12260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12297bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.resumeCurrentTab();
12300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = false;
12317bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        resumeWebViewTimers();
12320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mWakeLock.isHeld()) {
12340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(RELEASE_WAKELOCK);
12350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.release();
12360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null) {
12390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
12400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // In case credential request never comes back
12410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
12420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        registerReceiver(mNetworkStateIntentReceiver,
12460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                         mNetworkStateChangedFilter);
12470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.enablePlatformNotifications();
12480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.doFlick()) {
12500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSensorManager == null) {
12510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSensorManager = (SensorManager) getSystemService(
12520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Context.SENSOR_SERVICE);
12530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
12540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.registerListener(mSensorListener,
12550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_ACCELEROMETER,
12560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    SensorManager.SENSOR_DELAY_FASTEST);
12570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
12580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager = null;
12590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
12630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState(Bundle map)
12640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  onSaveInstanceState is called right before onStop(). The map contains
12650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  the saved state.
12660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
12670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onSaveInstanceState(Bundle outState) {
126831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
12690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
12700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the default implementation requires each view to have an id. As the
12720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // browser handles the state itself and it doesn't use id for the views,
12730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // don't call the default implementation. Otherwise it will trigger the
12740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // warning like this, "couldn't save which view has focus because the
12750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // focused view XXX has no id".
12760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save all the tabs
12780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.saveState(outState);
12790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
12800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onPause() {
12820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPause();
12830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause) {
12850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "BrowserActivity is already paused.");
12860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
12870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12897bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        mTabControl.pauseCurrentTab();
12900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mActivityInPause = true;
12917bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebViewTimers()) {
12920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mWakeLock.acquire();
12930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler
12940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
12950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
12960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
12970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the credentials toast if it is up
12980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg != null && mCredsDlg.isShowing()) {
12990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
13000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
13020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
13040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // unregister network state listener
13060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        unregisterReceiver(mNetworkStateIntentReceiver);
13070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.disablePlatformNotifications();
13080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSensorManager != null) {
13100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSensorManager.unregisterListener(mSensorListener);
13110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override protected void onDestroy() {
131531a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
13160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
13170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onDestroy();
13190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the current tab and sub window
13200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab t = mTabControl.getCurrentTab();
1321fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        if (t != null) {
1322fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            dismissSubWindow(t);
1323fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott            removeTabFromContentView(t);
1324fb5e77fac7b8b311fe72827183f8988f5ee92a5fPatrick Scott        }
13250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Destroy all the tabs
13260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.destroy();
13270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebIconDatabase.getInstance().close();
13280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mGlsConnection != null) {
13290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            unbindService(mGlsConnection);
13300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mGlsConnection = null;
13310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
13340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // stop MASF proxy service
13350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //
13360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //Intent proxyServiceIntent = new Intent();
13370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //proxyServiceIntent.setComponent
13380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //   (new ComponentName(
13390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice",
13400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        "com.android.masfproxyservice.MasfProxyService"));
13410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //stopService(proxyServiceIntent);
1342b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
1343b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba        unregisterReceiver(mPackageInstallationReceiver);
13440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
13470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
13480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onConfigurationChanged(newConfig);
13490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mPageInfoDialog != null) {
13510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mPageInfoDialog.dismiss();
13520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showPageInfo(
13530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoView,
13540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageInfoFromShowSSLCertificateOnError.booleanValue());
13550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateDialog != null) {
13570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateDialog.dismiss();
13580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificate(
13590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateView);
13600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSSLCertificateOnErrorDialog != null) {
13620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mSSLCertificateOnErrorDialog.dismiss();
13630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showSSLCertificateOnError(
13640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorView,
13650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorHandler,
13660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mSSLCertificateOnErrorError);
13670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mHttpAuthenticationDialog != null) {
13690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String title = ((TextView) mHttpAuthenticationDialog
13700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
13710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .toString();
13720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String name = ((TextView) mHttpAuthenticationDialog
13730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.username_edit)).getText().toString();
13740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = ((TextView) mHttpAuthenticationDialog
13750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .findViewById(R.id.password_edit)).getText().toString();
13760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
13770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .getId();
13780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHttpAuthenticationDialog.dismiss();
13790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            showHttpAuthentication(mHttpAuthHandler, null, null, title,
13800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    name, password, focusId);
13810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mFindDialog != null && mFindDialog.isShowing()) {
13830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mFindDialog.onConfigurationChanged(newConfig);
13840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
13850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public void onLowMemory() {
13880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onLowMemory();
13890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.freeMemory();
13900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
13910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
13927bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean resumeWebViewTimers() {
13930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if ((!mActivityInPause && !mPageStarted) ||
13940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (mActivityInPause && mPageStarted)) {
13950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().startSync();
13960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
13970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
13980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.resumeTimers();
13990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
14000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
14010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
14020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
14030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14067bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed    private boolean pauseWebViewTimers() {
14070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mActivityInPause && !mPageStarted) {
14080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().stopSync();
14090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebView w = mTabControl.getCurrentWebView();
14100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (w != null) {
14110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                w.pauseTimers();
14120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
14130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
14140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
14150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
14160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
14200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This function is called when we are launching for the first time. We
14210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * are waiting for the login credentials before loading Google home
14220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * pages. This way the user will be logged in straight away.
14230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
14240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void waitForCredentials() {
14250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show a toast
14260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = new ProgressDialog(this);
14270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setIndeterminate(true);
14280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
14290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the user cancels the operation, then cancel the Google
14300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Credentials request.
14310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
14320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg.show();
14330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // We set a timeout for the retrieval of credentials in onResume()
14350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // as that is when we have freed up some CPU time to get
14360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the login credentials.
14370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
14400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If we have received the credentials or we have timed out and we are
14410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * showing the credentials dialog, then it is time to move on.
14420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
14430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resumeAfterCredentials() {
14440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg == null) {
14450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
14460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear the toast
14490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mCredsDlg.isShowing()) {
14500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mCredsDlg.dismiss();
14510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCredsDlg = null;
14530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Clear any pending timeout
14550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
14560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the page
14580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
14590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
14600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.loadUrl(mSettings.getHomePage());
14610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Update the settings, need to do this last as it can take a moment
14640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to persist the settings. In the mean time we could be loading
14650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // content.
14660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSettings.setLoginInitialized(this);
14670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Open the icon database and retain all the icons for visited sites.
14700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void retainIconsOnStartup() {
14710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebIconDatabase db = WebIconDatabase.getInstance();
14720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        db.open(getDir("icons", 0).getPath());
14730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
14740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Cursor c = Browser.getAllBookmarks(mResolver);
14750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!c.moveToFirst()) {
14760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.deactivate();
14770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
14780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
14790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
14800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            do {
14810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = c.getString(urlIndex);
14820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                db.retainIconForPageUrl(url);
14830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } while (c.moveToNext());
14840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            c.deactivate();
14850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (IllegalStateException e) {
14860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "retainIconsOnStartup", e);
14870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
14880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Helper method for getting the top window.
14910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    WebView getTopWindow() {
14920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getCurrentTopWebView();
14930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
14940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
14960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
14970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onCreateOptionsMenu(menu);
14980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
14990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
15000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browser, menu);
15010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenu = menu;
15020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateInLoadMenuItems();
15030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
15070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * As the menu can be open when loading state changes
15080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * we must manually update the state of the stop/reload menu
15090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * item
15100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
15110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateInLoadMenuItems() {
15120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mMenu == null) {
15130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
15140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem src = mInLoad ?
15160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenu.findItem(R.id.stop_menu_id):
15170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mMenu.findItem(R.id.reload_menu_id);
15180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
15190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setIcon(src.getIcon());
15200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dest.setTitle(src.getTitle());
15210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onContextItemSelected(MenuItem item) {
15250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // chording is not an issue with context menus, but we use the same
15260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // options selector, so set mCanChord to true so we can access them.
15270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
15280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int id = item.getItemId();
15290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView webView = getTopWindow();
15300d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        if (null == webView) {
15310d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
15320d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
15330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final HashMap hrefMap = new HashMap();
15340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        hrefMap.put("webview", webView);
15350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Message msg = mHandler.obtainMessage(
15360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                FOCUS_NODE_HREF, id, 0, hrefMap);
15370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (id) {
15380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Browser context menu
15390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_context_menu_id:
15400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.open_newtab_context_menu_id:
15410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_context_menu_id:
15420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.save_link_context_menu_id:
15430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_link_context_menu_id:
15440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.copy_link_context_menu_id:
15450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                webView.requestFocusNodeHref(msg);
15460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
15490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // For other context menus
15500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return onOptionsItemSelected(item);
15510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
15530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Bundle createGoogleSearchSourceBundle(String source) {
15570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Bundle bundle = new Bundle();
15580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        bundle.putString(SearchManager.SOURCE, source);
15590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return bundle;
15600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
15634e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project     * Overriding this to insert a local information bundle
15640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
15650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onSearchRequested() {
15670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startSearch(null, false,
15684e5f58704099c37186d4825c3d55ea5b0527867fThe Android Open Source Project                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), false);
15690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
15700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void startSearch(String initialQuery, boolean selectInitialQuery,
15740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Bundle appSearchData, boolean globalSearch) {
15750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (appSearchData == null) {
15760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
15770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
15790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
15800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
15810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
15820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
15830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!mCanChord) {
15840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The user has already fired a shortcut with this hold down of the
15850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // menu key.
15860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
15870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
15880d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        if (null == mTabOverview && null == getTopWindow()) {
15890d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins            return false;
15900d7ae0ed82e21d472cde8cf92b5657d8ee8ca0d8Leon Scroggins        }
15910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (item.getItemId()) {
15920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Main menu
15930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.goto_menu_id: {
15940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String url = getTopWindow().getUrl();
15950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
15960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_GOTO), false);
15970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
15980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
15990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmarks_menu_id:
16010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(false);
16020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.windows_menu_id:
16050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getTabCount() == 1) {
1606f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    openTabAndShow(mSettings.getHomePage(), null, false, null);
16070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
16080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    tabPicker(true, mTabControl.getCurrentIndex(), false);
16090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.stop_reload_menu_id:
16130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mInLoad) {
16140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
16150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
16160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getTopWindow().reload();
16170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.back_menu_id:
16210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goBack();
16220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.forward_menu_id:
16250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().goForward();
16260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.close_menu_id:
16290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Close the subwindow if it exists.
16300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getCurrentSubWindow() != null) {
16310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(mTabControl.getCurrentTab());
16320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
16330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final int currentIndex = mTabControl.getCurrentIndex();
16350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab parent =
16360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getCurrentTab().getParentTab();
16370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int indexToShow = -1;
16380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (parent != null) {
16390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    indexToShow = mTabControl.getTabIndex(parent);
16400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
16410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Get the last tab in the list. If it is the current tab,
16420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // subtract 1 more.
16430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    indexToShow = mTabControl.getTabCount() - 1;
16440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (currentIndex == indexToShow) {
16450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        indexToShow--;
16460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
16470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                switchTabs(currentIndex, indexToShow, true);
16490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.homepage_menu_id:
16520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TabControl.Tab current = mTabControl.getCurrentTab();
16530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current != null) {
16540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(current);
16550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current.getWebView().loadUrl(mSettings.getHomePage());
16560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.preferences_menu_id:
16600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent intent = new Intent(this,
16610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        BrowserPreferencesPage.class);
16620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                startActivityForResult(intent, PREFERENCES_PAGE);
16630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.find_menu_id:
16660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (null == mFindDialog) {
16670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mFindDialog = new FindDialog(this);
16680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
16690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.setWebView(getTopWindow());
16700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mFindDialog.show();
16710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mMenuState = EMPTY_MENU;
16720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.select_text_id:
16750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().emulateShiftHeld();
16760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.page_info_menu_id:
16780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showPageInfo(mTabControl.getCurrentTab(), false);
16790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.classic_history_menu_id:
16820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(true);
16830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.share_page_menu_id:
16860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Browser.sendString(this, getTopWindow().getUrl());
16870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.dump_nav_menu_id:
16900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().debugDump();
16910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_in_menu_id:
16940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomIn();
16950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
16960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
16970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.zoom_out_menu_id:
16980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getTopWindow().zoomOut();
16990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_downloads_menu_id:
17020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                viewDownloads(null);
17030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // -- Tab menu
17060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.view_tab_menu_id:
17070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
17080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
17090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabOverview.setCurrentIndex(pos);
17100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabListener.onClick(pos);
17110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.remove_tab_menu_id:
17150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
17160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
17170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabListener.remove(pos);
17180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.new_tab_menu_id:
17220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // No need to check for mTabOverview here since we are not
17230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // dependent on it for a position.
17240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null) {
17250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // If the overview happens to be non-null, make the "New
17260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Tab" cell visible.
17270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabOverview != null) {
17280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabOverview.setCurrentIndex(ImageGrid.NEW_TAB);
17290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
17300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabListener.onClick(ImageGrid.NEW_TAB);
17310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmark_tab_menu_id:
17350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
17360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
17370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    TabControl.Tab t = mTabControl.getTab(pos);
17380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Since we called populatePickerData for all of the
17390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // tabs, getTitle and getUrl will return appropriate
17400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // values.
17410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Browser.saveBookmark(BrowserActivity.this, t.getTitle(),
17420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            t.getUrl());
17430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.history_tab_menu_id:
17470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(true);
17480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.bookmarks_tab_menu_id:
17510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(false);
17520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.properties_tab_menu_id:
17550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabListener != null && mTabOverview != null) {
17560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int pos = mTabOverview.getContextMenuPosition(item);
17570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    showPageInfo(mTabControl.getTab(pos), false);
17580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_one_menu_id:
17620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_two_menu_id:
17630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_three_menu_id:
17640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_four_menu_id:
17650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_five_menu_id:
17660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_six_menu_id:
17670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_seven_menu_id:
17680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.window_eight_menu_id:
17690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                {
17700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    int menuid = item.getItemId();
17710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
17720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
17730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            TabControl.Tab desiredTab = mTabControl.getTab(id);
17740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (desiredTab != null &&
17750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    desiredTab != mTabControl.getCurrentTab()) {
17760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                switchTabs(mTabControl.getCurrentIndex(), id, false);
17770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
17780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
17790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
17800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
17810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
17830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
17850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!super.onOptionsItemSelected(item)) {
17860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
17870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
17880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Otherwise fall through.
17890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
17900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = false;
17910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
17920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void closeFind() {
17950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = R.id.MAIN_MENU;
17960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
17970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
17980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onPrepareOptionsMenu(Menu menu)
17990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    {
18000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // This happens when the user begins to hold down the menu key, so
18010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // allow them to chord to get a shortcut.
18020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCanChord = true;
18030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note: setVisible will decide whether an item is visible; while
18040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // setEnabled() will decide whether an item is enabled, which also means
18050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // whether the matching shortcut key will function.
18060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        super.onPrepareOptionsMenu(menu);
18070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (mMenuState) {
18080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case R.id.TAB_MENU:
18090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
18100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
18110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
18120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
18130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.TAB_MENU, true);
18140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.TAB_MENU, true);
18150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean newT = mTabControl.getTabCount() < TabControl.MAX_TABS;
18170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem tab = menu.findItem(R.id.new_tab_menu_id);
18180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                tab.setVisible(newT);
18190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                tab.setEnabled(newT);
18200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case EMPTY_MENU:
18220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
18230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, false);
18240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
18250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
18260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.TAB_MENU, false);
18270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.TAB_MENU, false);
18280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
18310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mCurrentMenuState != mMenuState) {
18320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.MAIN_MENU, true);
18330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
18340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
18350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupVisible(R.id.TAB_MENU, false);
18360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setGroupEnabled(R.id.TAB_MENU, false);
18370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final WebView w = getTopWindow();
18390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoBack = false;
18400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean canGoForward = false;
18410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isHome = false;
18420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (w != null) {
18430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoBack = w.canGoBack();
18440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    canGoForward = w.canGoForward();
18450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    isHome = mSettings.getHomePage().equals(w.getUrl());
18460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
18470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem back = menu.findItem(R.id.back_menu_id);
18480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                back.setEnabled(canGoBack);
18490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
18510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                home.setEnabled(!isHome);
18520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.forward_menu_id)
18540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setEnabled(canGoForward);
18550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the share link option
18570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
18580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
18590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
18600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
18610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
18620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // If there is only 1 window, the text will be "New window"
18640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem windows = menu.findItem(R.id.windows_menu_id);
18650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                windows.setTitleCondensed(mTabControl.getTabCount() > 1 ?
18660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getString(R.string.view_tabs_condensed) :
18670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getString(R.string.tab_picker_new_tab));
18680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isNavDump = mSettings.isNavDump();
18700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
18710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setVisible(isNavDump);
18720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                nav.setEnabled(isNavDump);
18730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
18740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mCurrentMenuState = mMenuState;
18760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return true;
18770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
18780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
18800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onCreateContextMenu(ContextMenu menu, View v,
18810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ContextMenuInfo menuInfo) {
18820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView webview = (WebView) v;
18830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView.HitTestResult result = webview.getHitTestResult();
18840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (result == null) {
18850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
18860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int type = result.getType();
18890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
18900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG,
18910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "We should not show context menu when nothing is touched");
18920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
18930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
18950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // let TextView handles context menu
18960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
18970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
18980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
18990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Note, http://b/issue?id=1106666 is requesting that
19000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // an inflated menu can be used again. This is not available
19010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // yet, so inflate each time (yuk!)
19020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        MenuInflater inflater = getMenuInflater();
19030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        inflater.inflate(R.menu.browsercontext, menu);
19040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Show the correct menu group
19060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String extra = result.getExtra();
19070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.PHONE_MENU,
19080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.PHONE_TYPE);
19090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.EMAIL_MENU,
19100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.EMAIL_TYPE);
19110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.GEO_MENU,
19120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.GEO_TYPE);
19130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.IMAGE_MENU,
19140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.IMAGE_TYPE
19150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
19160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        menu.setGroupVisible(R.id.ANCHOR_MENU,
19170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
19180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
19190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setup custom handling depending on the type
19210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (type) {
19220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.PHONE_TYPE:
19230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(Uri.decode(extra));
19240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.dial_context_menu_id).setIntent(
19250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
19260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_TEL + extra)));
19270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
19280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
19290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                addIntent.setType(Contacts.People.CONTENT_ITEM_TYPE);
19300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
19310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        addIntent);
19320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
19330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
19340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.EMAIL_TYPE:
19370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
19380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.email_context_menu_id).setIntent(
19390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
19400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_MAILTO + extra)));
19410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
19420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
19430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.GEO_TYPE:
19460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderTitle(extra);
19470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.map_context_menu_id).setIntent(
19480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri
19490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .parse(WebView.SCHEME_GEO
19500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        + URLEncoder.encode(extra))));
19510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
19520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Copy(extra));
19530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
19560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
19570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                TextView titleView = (TextView) LayoutInflater.from(this)
19580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(android.R.layout.browser_link_context_header,
19590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        null);
19600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                titleView.setText(extra);
19610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.setHeaderView(titleView);
19620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // decide whether to show the open link in new tab option
19630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
19640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getTabCount() < TabControl.MAX_TABS);
19650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                PackageManager pm = getPackageManager();
19660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Intent send = new Intent(Intent.ACTION_SEND);
19670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                send.setType("text/plain");
19680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
19690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
19700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
19710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
19720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
19730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // otherwise fall through to handle image part
19740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case WebView.HitTestResult.IMAGE_TYPE:
19750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (type == WebView.HitTestResult.IMAGE_TYPE) {
19760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    menu.setHeaderTitle(extra);
19770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
19780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.view_image_context_menu_id).setIntent(
19790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
19800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                menu.findItem(R.id.download_context_menu_id).
19810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        setOnMenuItemClickListener(new Download(extra));
19820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
19850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.w(LOGTAG, "We should not get here.");
19860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
19870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
19880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
19890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
19900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach the given tab to the content view.
19910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachTabToContentView(TabControl.Tab t) {
19920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView main = t.getWebView();
19930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the main WebView.
19940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(main, COVER_SCREEN_PARAMS);
19950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the sub window if necessary
19960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        attachSubWindow(t);
19970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Request focus on the top window.
19980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        t.getTopWindow().requestFocus();
19990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Attach a sub window to the main WebView of the given tab.
20020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void attachSubWindow(TabControl.Tab t) {
20030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If a sub window exists, attach it to the content view.
20040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView subView = t.getSubWebView();
20050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (subView != null) {
20060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final View container = t.getSubWebViewContainer();
20070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContentView.addView(container, COVER_SCREEN_PARAMS);
20080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            subView.requestFocus();
20090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the given tab from the content view.
20130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void removeTabFromContentView(TabControl.Tab t) {
2014cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project        // Remove the main WebView.
20150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.removeView(t.getWebView());
20160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the sub window if it exists.
20170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (t.getSubWebView() != null) {
20180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContentView.removeView(t.getSubWebViewContainer());
20190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Remove the sub window if it exists. Also called by TabControl when the
20230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // user clicks the 'X' to dismiss a sub window.
20240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void dismissSubWindow(TabControl.Tab t) {
20250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView mainView = t.getWebView();
20260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (t.getSubWebView() != null) {
20270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Remove the container view and request focus on the main WebView.
20280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mContentView.removeView(t.getSubWebViewContainer());
20290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mainView.requestFocus();
20300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Tell the TabControl to dismiss the subwindow. This will destroy
20310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the WebView.
20320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.dismissSubWindow(t);
20330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Send the ANIMTE_FROM_OVERVIEW message after changing the current tab.
20370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void sendAnimateFromOverview(final TabControl.Tab tab,
203825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            final boolean newTab, final UrlData urlData, final int delay,
20390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Message msg) {
20400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Set the current tab.
20410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabControl.setCurrentTab(tab);
20420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the WebView so it will layout.
20430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        attachTabToContentView(tab);
20440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Set the view to invisibile for now.
20450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        tab.getWebView().setVisibility(View.INVISIBLE);
20460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If there is a sub window, make it invisible too.
20470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (tab.getSubWebView() != null) {
20480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tab.getSubWebViewContainer().setVisibility(View.INVISIBLE);
20490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create our fake animating view.
20510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final AnimatingView view = new AnimatingView(this, tab);
20520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach it to the view system and make in invisible so it will
20530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // layout but not flash white on the screen.
20540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(view, COVER_SCREEN_PARAMS);
20550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        view.setVisibility(View.INVISIBLE);
20560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Send the animate message.
20570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final HashMap map = new HashMap();
20580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        map.put("view", view);
20590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Load the url after the AnimatingView has captured the picture. This
20600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // prevents any bad layout or bad scale from being used during
20610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // animation.
206225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        if (!urlData.isEmpty()) {
20630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dismissSubWindow(tab);
206425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            urlData.loadIn(tab.getWebView());
20650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        map.put("msg", msg);
20670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessageDelayed(mHandler.obtainMessage(
20680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                ANIMATE_FROM_OVERVIEW, newTab ? 1 : 0, 0, map), delay);
20690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Increment the count to indicate that we are in an animation.
20700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mAnimationCount++;
20710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Remove the listener so we don't get any more tab changes.
20720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview.setListener(null);
20730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabListener = null;
20740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the menu empty until the animation completes.
20750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = EMPTY_MENU;
20760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
20780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // 500ms animation with 800ms delay
208095d601f66135d078c113c58d9aaa6e4a76fd80f2Patrick Scott    private static final int TAB_ANIMATION_DURATION = 200;
208195d601f66135d078c113c58d9aaa6e4a76fd80f2Patrick Scott    private static final int TAB_OVERVIEW_DELAY     = 500;
20820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
20830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called by TabControl when a tab is requesting focus
20840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void showTab(TabControl.Tab t) {
208595d601f66135d078c113c58d9aaa6e4a76fd80f2Patrick Scott        showTab(t, EMPTY_URL_DATA);
2086f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project    }
2087f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project
208825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private void showTab(TabControl.Tab t, UrlData urlData) {
20890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Disallow focus change during a tab animation.
20900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount > 0) {
20910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
20920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
20930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int delay = 0;
20940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabOverview == null) {
20950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Add a delay so the tab overview can be shown before the second
20960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // animation begins.
20970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
20980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tabPicker(false, mTabControl.getTabIndex(t), false);
20990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
210025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        sendAnimateFromOverview(t, false, urlData, delay, null);
210125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    }
210225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
210325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // A wrapper function of {@link #openTabAndShow(UrlData, Message, boolean, String)}
210425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    // that accepts url as string.
2105f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima    private TabControl.Tab openTabAndShow(String url, final Message msg,
210625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            boolean closeOnExit, String appId) {
2107f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima        return openTabAndShow(new UrlData(url), msg, closeOnExit, appId);
21080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // This method does a ton of stuff. It will attempt to create a new tab
21110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
21120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // url isn't null, it will load the given url. If the tab overview is not
21130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // showing, it will animate to the tab overview, create a new tab and
21140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // animate away from it. After the animation completes, it will dispatch
21150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // the given Message. If the tab overview is already showing (i.e. this
21160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // method is called from TabListener.onClick(), the method will animate
21170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // away from the tab overview.
2118f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima    private TabControl.Tab openTabAndShow(UrlData urlData, final Message msg,
2119f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            boolean closeOnExit, String appId) {
21200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final boolean newTab = mTabControl.getTabCount() != TabControl.MAX_TABS;
21210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab currentTab = mTabControl.getCurrentTab();
21220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (newTab) {
21230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int delay = 0;
21240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If the tab overview is up and there are animations, just load
21250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // the url.
21260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mTabOverview != null && mAnimationCount > 0) {
212725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                if (!urlData.isEmpty()) {
21280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // We should not have a msg here since onCreateWindow
21290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // checks the animation count and every other caller passes
21300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // null.
21310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    assert msg == null;
21320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // just dismiss the subwindow and load the given url.
21330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    dismissSubWindow(currentTab);
213425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                    urlData.loadIn(currentTab.getWebView());
21350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // show mTabOverview if it is not there.
21380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabOverview == null) {
21390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // We have to delay the animation from the tab picker by the
21400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // length of the tab animation. Add a delay so the tab
21410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // overview can be shown before the second animation begins.
21420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
21430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    tabPicker(false, ImageGrid.NEW_TAB, false);
21440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
21450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Animate from the Tab overview after any animations have
21460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // finished.
2147c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                final TabControl.Tab tab = mTabControl.createNewTab(
2148f26aeabb17d38ed39a0711afcf51694cc69c8d51Mitsuru Oshima                        closeOnExit, appId, urlData.mUrl);
2149ec7eb37292836652e096b5804877e803e2505136Grace Kloba                sendAnimateFromOverview(tab, true, urlData, delay, msg);
2150c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                return tab;
21510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
215225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        } else if (!urlData.isEmpty()) {
21530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We should not have a msg here.
21540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            assert msg == null;
21550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mTabOverview != null && mAnimationCount == 0) {
215625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                sendAnimateFromOverview(currentTab, false, urlData,
21570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        TAB_OVERVIEW_DELAY, null);
21580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
21590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Get rid of the subwindow if it exists
21600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                dismissSubWindow(currentTab);
21610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Load the given url.
216225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima                urlData.loadIn(currentTab.getWebView());
21630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
21640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
2165c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba        return currentTab;
21660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Animation createTabAnimation(final AnimatingView view,
21690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final View cell, boolean scaleDown) {
21700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final AnimationSet set = new AnimationSet(true);
21710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final float scaleX = (float) cell.getWidth() / view.getWidth();
21720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final float scaleY = (float) cell.getHeight() / view.getHeight();
21730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (scaleDown) {
21740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new ScaleAnimation(1.0f, scaleX, 1.0f, scaleY));
21750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new TranslateAnimation(0, cell.getLeft(), 0,
21760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    cell.getTop()));
21770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
21780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new ScaleAnimation(scaleX, 1.0f, scaleY, 1.0f));
21790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            set.addAnimation(new TranslateAnimation(cell.getLeft(), 0,
21800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    cell.getTop(), 0));
21810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        set.setDuration(TAB_ANIMATION_DURATION);
21830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        set.setInterpolator(new DecelerateInterpolator());
21840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return set;
21850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
21860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
21870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Animate to the tab overview. currentIndex tells us which position to
21880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // animate to and newIndex is the position that should be selected after
21890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // the animation completes.
21900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If remove is true, after the animation stops, a confirmation dialog will
21910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be displayed to the user.
21920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void animateToTabOverview(final int newIndex, final boolean remove,
21930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AnimatingView view) {
21940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Find the view in the ImageGrid allowing for the "New Tab" cell.
21950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int position = mTabControl.getTabIndex(view.mTab);
21960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
21970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            position++;
21980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
21990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Offset the tab position with the first visible position to get a
22010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // number between 0 and 3.
22020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        position -= mTabOverview.getFirstVisiblePosition();
22030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Grab the view that we are going to animate to.
22050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = mTabOverview.getChildAt(position);
22060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Animation.AnimationListener l =
22080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new Animation.AnimationListener() {
22090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationStart(Animation a) {
2210d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                        if (mTabOverview != null) {
2211d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                            mTabOverview.requestFocus();
2212d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                            // Clear the listener so we don't trigger a tab
2213d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                            // selection.
2214d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                            mTabOverview.setListener(null);
2215d068f8015daa84296463fcc0420e40e35e40fe7dPatrick Scott                        }
22160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationRepeat(Animation a) {}
22180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationEnd(Animation a) {
22190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // We are no longer animating so decrement the count.
22200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mAnimationCount--;
22210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // Make the view GONE so that it will not draw between
22220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // now and when the Runnable is handled.
22230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        view.setVisibility(View.GONE);
22240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // Post a runnable since we can't modify the view
22250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // hierarchy during this callback.
22260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.post(new Runnable() {
22270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void run() {
22280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Remove the AnimatingView.
22290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mContentView.removeView(view);
22300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (mTabOverview != null) {
22310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Make newIndex visible.
22320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    mTabOverview.setCurrentIndex(newIndex);
22330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Restore the listener.
22340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    mTabOverview.setListener(mTabListener);
22350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Change the menu to TAB_MENU if the
22360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // ImageGrid is interactive.
22370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    if (mTabOverview.isLive()) {
22380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mMenuState = R.id.TAB_MENU;
22390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabOverview.requestFocus();
22400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    }
22410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
22420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // If a remove was requested, remove the tab.
22430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (remove) {
22440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // During a remove, the current tab has
22450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // already changed. Remember the current one
22460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // here.
22470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    final TabControl.Tab currentTab =
22480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            mTabControl.getCurrentTab();
22490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Remove the tab at newIndex from
22500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // TabControl and the tab overview.
22510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    final TabControl.Tab tab =
22520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            mTabControl.getTab(newIndex);
22530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    mTabControl.removeTab(tab);
22540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    // Restore the current tab.
22550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    if (currentTab != tab) {
22560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabControl.setCurrentTab(currentTab);
22570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    }
22580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    if (mTabOverview != null) {
22590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabOverview.remove(newIndex);
22600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        // Make the current tab visible.
22610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabOverview.setCurrentIndex(
22620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                                mTabControl.getCurrentIndex());
22630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    }
22640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
22650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
22660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        });
22670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
22680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                };
22690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Do an animation if there is a view to animate to.
22710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (v != null) {
22720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Create our animation
22730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Animation anim = createTabAnimation(view, v, true);
22740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.setAnimationListener(l);
22750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Start animating
22760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            view.startAnimation(anim);
22770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
22780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If something goes wrong and we didn't find a view to animate to,
22790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // just do everything here.
22800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l.onAnimationStart(null);
22810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l.onAnimationEnd(null);
22820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
22840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
22850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Animate from the tab picker. The index supplied is the index to animate
22860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // from.
22870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void animateFromTabOverview(final AnimatingView view,
22880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final boolean newTab, final Message msg) {
22890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // firstVisible is the first visible tab on the screen.  This helps
22900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to know which corner of the screen the selected tab is.
22910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int firstVisible = mTabOverview.getFirstVisiblePosition();
22920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // tabPosition is the 0-based index of of the tab being opened
22930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int tabPosition = mTabControl.getTabIndex(view.mTab);
22940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
22950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Add one to make room for the "New Tab" cell.
22960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tabPosition++;
22970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
22980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If this is a new tab, animate from the "New Tab" cell.
22990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (newTab) {
23000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            tabPosition = 0;
23010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Location corresponds to the four corners of the screen.
23030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // A new tab or 0 is upper left, 0 for an old tab is upper
23040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // right, 1 is lower left, and 2 is lower right
23050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int location = tabPosition - firstVisible;
23060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Find the view at this location.
23080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = mTabOverview.getChildAt(location);
23090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Wait until the animation completes to replace the AnimatingView.
23110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final Animation.AnimationListener l =
23120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new Animation.AnimationListener() {
23130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationStart(Animation a) {}
23140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationRepeat(Animation a) {}
23150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onAnimationEnd(Animation a) {
23160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.post(new Runnable() {
23170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void run() {
23180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mContentView.removeView(view);
23190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Dismiss the tab overview. If the cell at the
23200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // given location is null, set the fade
23210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // parameter to true.
23220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                dismissTabOverview(v == null);
23230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                TabControl.Tab t =
23240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        mTabControl.getCurrentTab();
23250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mMenuState = R.id.MAIN_MENU;
23260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Resume regular updates.
23270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                t.getWebView().resumeTimers();
23280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Dispatch the message after the animation
23290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // completes.
23300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (msg != null) {
23310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    msg.sendToTarget();
23320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
23330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // The animation is done and the tab overview is
23340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // gone so allow key events and other animations
23350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // to begin.
23360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mAnimationCount--;
23370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // Reset all the title bar info.
23380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                resetTitle();
23390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
23400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        });
23410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
23420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                };
23430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (v != null) {
23450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Animation anim = createTabAnimation(view, v, false);
23460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Set the listener and start animating
23470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.setAnimationListener(l);
23480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            view.startAnimation(anim);
23490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Make the view VISIBLE during the animation.
23500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            view.setVisibility(View.VISIBLE);
23510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
23520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Go ahead and do all the cleanup.
23530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l.onAnimationEnd(null);
23540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dismiss the tab overview applying a fade if needed.
23580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void dismissTabOverview(final boolean fade) {
23590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fade) {
23600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f);
23610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.setDuration(500);
23620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            anim.startNow();
23630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabOverview.startAnimation(anim);
23640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case there was a problem with animating away from the tab
23660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // overview
23670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
23680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current != null) {
23690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            current.setVisibility(View.VISIBLE);
23700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
23710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "No current WebView in dismissTabOverview");
23720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the sub window container visible.
23740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabControl.getCurrentSubWindow() != null) {
23750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.getCurrentTab().getSubWebViewContainer()
23760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setVisibility(View.VISIBLE);
23770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.removeView(mTabOverview);
23792ed6edb70dae14691de2109e97fd54feedd84464Patrick Scott        // Clear all the data for tab picker so next time it will be
23802ed6edb70dae14691de2109e97fd54feedd84464Patrick Scott        // recreated.
23812ed6edb70dae14691de2109e97fd54feedd84464Patrick Scott        mTabControl.wipeAllPickerData();
23820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview.clear();
23830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview = null;
23840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabListener = null;
23850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
2387c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba    private TabControl.Tab openTab(String url) {
23880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mSettings.openInBackground()) {
2389f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project            TabControl.Tab t = mTabControl.createNewTab();
23900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (t != null) {
23910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                t.getWebView().loadUrl(url);
23920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
2393c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return t;
23940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
2395c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba            return openTabAndShow(url, null, false, null);
23960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
23970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
23980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
23990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Copy implements OnMenuItemClickListener {
24000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private CharSequence mText;
24010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
24030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            copy(mText);
24040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
24050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Copy(CharSequence toCopy) {
24080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toCopy;
24090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class Download implements OnMenuItemClickListener {
24130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private String mText;
24140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
24160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            onDownloadStartNoStream(mText, null, null, null, -1);
24170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
24180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public Download(String toDownload) {
24210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mText = toDownload;
24220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void copy(CharSequence text) {
24260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
24270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
24280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (clip != null) {
24290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                clip.setClipboardText(text);
24300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
24310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (android.os.RemoteException e) {
24320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Copy failed", e);
24330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be (for example, if we
24380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * load a page from history).
24390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitle() {
24410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetLockIcon();
24420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
24430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the browser title-view to whatever it must be
24470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if we had a loading error)
24480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * When we have a new page, we call resetTitle, when we
24490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * have to reset the titlebar to whatever it used to be
24500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (for example, if the user chose to stop loading), we
24510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * call resetTitleAndRevertLockIcon.
24520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void resetTitleAndRevertLockIcon() {
24540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        revertLockIcon();
24550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleIconAndProgress();
24560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reset the title, favicon, and progress.
24600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleIconAndProgress() {
24620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
24630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
24640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
24650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndIcon(current);
24670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int progress = current.getProgress();
24680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebChromeClient.onProgressChanged(current, progress);
24690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Reset the title and the icon based on the given item.
24720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetTitleAndIcon(WebView view) {
24730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
24740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (item != null) {
24750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(item.getUrl(), item.getTitle());
24760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(item.getFavicon());
24770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
24780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(null, null);
24790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setFavicon(null);
24800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
24810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
24820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
24840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Sets a title composed of the URL and the title string.
24850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
24860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
24870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
24880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setUrlTitle(String url, String title) {
24890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mUrl = url;
24900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTitle = title;
24910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
24920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // While the tab overview is animating or being shown, block changes
24930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // to the title.
24940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount == 0 && mTabOverview == null) {
249581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            if (CUSTOM_BROWSER_BAR) {
249681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                mTitleBar.setTitleAndUrl(title, url);
249781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            } else {
249881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                setTitle(buildUrlTitle(url, title));
249981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            }
25000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
25040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Builds and returns the page title, which is some
25050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * combination of the page URL and title.
25060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL of the site being loaded.
25070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param title The title of the site being loaded.
25080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The page title.
25090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
25100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String buildUrlTitle(String url, String title) {
25110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String urlTitle = "";
25120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
25140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String titleUrl = buildTitleUrl(url);
25150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (title != null && 0 < title.length()) {
25170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (titleUrl != null && 0 < titleUrl.length()) {
25180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    urlTitle = titleUrl + ": " + title;
25190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
25200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    urlTitle = title;
25210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
25230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (titleUrl != null) {
25240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    urlTitle = titleUrl;
25250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
25270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return urlTitle;
25300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
25330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The URL to build a title version of the URL from.
25340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The title version of the URL or null if fails.
25350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * The title version of the URL can be either the URL hostname,
25360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or the hostname with an "https://" prefix (for secure URLs),
25370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * or an empty string if, for example, the URL in question is a
25380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * file:// URL with no hostname.
25390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
254032e14a6deccfa75490b3032bb4ddd5ae90f89de8Leon Scroggins    /* package */ static String buildTitleUrl(String url) {
25410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleUrl = null;
25420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null) {
25440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
25450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // parse the url string
25460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                URL urlObj = new URL(url);
25470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (urlObj != null) {
25480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    titleUrl = "";
25490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String protocol = urlObj.getProtocol();
25510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String host = urlObj.getHost();
25520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (host != null && 0 < host.length()) {
25540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        titleUrl = host;
25550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (protocol != null) {
25560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // if a secure site, add an "https://" prefix!
25570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (protocol.equalsIgnoreCase("https")) {
25580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                titleUrl = protocol + "://" + host;
25590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
25600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
25610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
25620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
25630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (MalformedURLException e) {}
25640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
25650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return titleUrl;
25670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
25680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
25690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Set the favicon in the title bar.
25700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void setFavicon(Bitmap icon) {
25710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // While the tab overview is animating or being shown, block changes to
25720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // the favicon.
25730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount > 0 || mTabOverview != null) {
25740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
25750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
257681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        if (CUSTOM_BROWSER_BAR) {
257781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            Drawable[] array = new Drawable[3];
257881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            array[0] = new PaintDrawable(Color.BLACK);
257981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            PaintDrawable p = new PaintDrawable(Color.WHITE);
258081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            array[1] = p;
258181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            if (icon == null) {
258281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                array[2] = mGenericFavicon;
258381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            } else {
258481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                array[2] = new BitmapDrawable(icon);
258581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            }
258681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            LayerDrawable d = new LayerDrawable(array);
258781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            d.setLayerInset(1, 1, 1, 1, 1);
258881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            d.setLayerInset(2, 2, 2, 2, 2);
258981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            mTitleBar.setFavicon(d);
25900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
259181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            Drawable[] array = new Drawable[2];
259281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            PaintDrawable p = new PaintDrawable(Color.WHITE);
259381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            p.setCornerRadius(3f);
259481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            array[0] = p;
259581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            if (icon == null) {
259681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                array[1] = mGenericFavicon;
259781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            } else {
259881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                array[1] = new BitmapDrawable(icon);
259981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            }
260081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            LayerDrawable d = new LayerDrawable(array);
260181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            d.setLayerInset(1, 2, 2, 2, 2);
260281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, d);
26030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
26070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Saves the current lock-icon state before resetting
26080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the lock icon. If we have an error, we may need to
26090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * roll back to the previous state.
26100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
26110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void saveLockIcon() {
26120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPrevLockType = mLockIconType;
26130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
26160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Reverts the lock-icon state to the last saved state,
26170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * for example, if we had an error, and need to cancel
26180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the load.
26190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
26200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void revertLockIcon() {
26210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = mPrevLockType;
26220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
262331a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
26240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.v(LOGTAG, "BrowserActivity.revertLockIcon:" +
26250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  " revert lock icon to " + mLockIconType);
26260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(mLockIconType);
26290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void switchTabs(int indexFrom, int indexToShow, boolean remove) {
26320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
26330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Animate to the tab picker, remove the current tab, then
26340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // animate away from the tab picker to the parent WebView.
26350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        tabPicker(false, indexFrom, remove);
26360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Change to the parent tab
26370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab tab = mTabControl.getTab(indexToShow);
26380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (tab != null) {
263995d601f66135d078c113c58d9aaa6e4a76fd80f2Patrick Scott            sendAnimateFromOverview(tab, false, EMPTY_URL_DATA, delay, null);
26400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
26410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Increment this here so that no other animations can happen in
26420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // between the end of the tab picker transition and the beginning
26430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // of openTabAndShow. This has a matching decrement in the handler
26440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // of OPEN_TAB_AND_SHOW.
26450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mAnimationCount++;
26460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Send a message to open a new tab.
26470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(
26480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mHandler.obtainMessage(OPEN_TAB_AND_SHOW,
26490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mSettings.getHomePage()), delay);
26500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void goBackOnePageOrQuit() {
26540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabControl.Tab current = mTabControl.getCurrentTab();
26550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
26560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
26570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Instead of finishing the activity, simply push this to the back
26580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * of the stack and let ActivityManager to choose the foreground
26590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * activity. As BrowserActivity is singleTask, it will be always the
26600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * root of the task. So we can use either true or false for
26610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * moveTaskToBack().
26620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
26630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            moveTaskToBack(true);
26640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = current.getWebView();
26660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w.canGoBack()) {
26670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.goBack();
26680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
26690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if we are closing a window that was created by
26700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // another window. If so, we switch back to that window.
26710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            TabControl.Tab parent = current.getParentTab();
26720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
26730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                switchTabs(mTabControl.getCurrentIndex(),
26740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getTabIndex(parent), true);
26750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
26760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (current.closeOnExit()) {
26770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mTabControl.getTabCount() == 1) {
26780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        finish();
26790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        return;
26800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
26817bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // call pauseWebViewTimers() now, we won't be able to call
26827bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    // it in onPause() as the WebView won't be valid.
26837bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                    pauseWebViewTimers();
26840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    removeTabFromContentView(current);
26850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.removeTab(current);
26860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
26870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                /*
26880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * Instead of finishing the activity, simply push this to the back
26890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * of the stack and let ActivityManager to choose the foreground
26900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * activity. As BrowserActivity is singleTask, it will be always the
26910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * root of the task. So we can use either true or false for
26920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 * moveTaskToBack().
26930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 */
26940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                moveTaskToBack(true);
26950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
26960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
26970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
26980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
26990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public KeyTracker.State onKeyTracker(int keyCode,
27000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                         KeyEvent event,
27010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                         KeyTracker.Stage stage,
27020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                         int duration) {
27030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if onKeyTracker() is called after activity onStop()
27040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // because of accumulated key events,
27050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // we should ignore it as browser is not active any more.
27060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView topWindow = getTopWindow();
2707adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        if (topWindow == null && mCustomView == null)
27080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return KeyTracker.State.NOT_TRACKING;
27090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_BACK) {
2711adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Check if a custom view is currently showing and, if it is, hide it.
2712adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            if (mCustomView != null) {
2713adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                mWebChromeClient.onHideCustomView();
2714adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                return KeyTracker.State.DONE_TRACKING;
2715adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            }
27160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // During animations, block the back key so that other animations
27170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not triggered and so that we don't end up destroying all the
27180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // WebViews before finishing the animation.
27190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAnimationCount > 0) {
27200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return KeyTracker.State.DONE_TRACKING;
27210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (stage == KeyTracker.Stage.LONG_REPEAT) {
27230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                bookmarksOrHistoryPicker(true);
27240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return KeyTracker.State.DONE_TRACKING;
27250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (stage == KeyTracker.Stage.UP) {
27260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // FIXME: Currently, we do not have a notion of the
27270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // history picker for the subwindow, but maybe we
27280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // should?
27290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView subwindow = mTabControl.getCurrentSubWindow();
27300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (subwindow != null) {
27310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (subwindow.canGoBack()) {
27320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        subwindow.goBack();
27330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
27340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dismissSubWindow(mTabControl.getCurrentTab());
27350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
27370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    goBackOnePageOrQuit();
27380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
27390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return KeyTracker.State.DONE_TRACKING;
27400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return KeyTracker.State.KEEP_TRACKING;
27420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return KeyTracker.State.NOT_TRACKING;
27440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
27470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_MENU) {
27480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mMenuIsDown = true;
27490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean handled =  mKeyTracker.doKeyDown(keyCode, event);
27510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!handled) {
27520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (keyCode) {
27530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case KeyEvent.KEYCODE_SPACE:
27540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (event.isShiftPressed()) {
27550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getTopWindow().pageUp(false);
27560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
27570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        getTopWindow().pageDown(false);
27580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
27590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    handled = true;
27600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                default:
27630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
27640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
27650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return handled || super.onKeyDown(keyCode, event);
27670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
27700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (keyCode == KeyEvent.KEYCODE_MENU) {
27710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mMenuIsDown = false;
27720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mKeyTracker.doKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
27740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void stopLoading() {
27770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        resetTitleAndRevertLockIcon();
27780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = getTopWindow();
27790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        w.stopLoading();
27800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mWebViewClient.onPageFinished(w, w.getUrl());
27810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        cancelStopToast();
27830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast = Toast
27840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
27850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mStopToast.show();
27860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void cancelStopToast() {
27890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mStopToast != null) {
27900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast.cancel();
27910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mStopToast = null;
27920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
27930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
27950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // called by a non-UI thread to post the message
27960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void postMessage(int what, int arg1, int arg2, Object obj) {
27970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2, obj));
27980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
27990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // public message ids
28010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int LOAD_URL                = 1001;
28020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public final static int STOP_LOAD               = 1002;
28030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Message Ids
28050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int FOCUS_NODE_HREF         = 102;
28060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CANCEL_CREDS_REQUEST    = 103;
28070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int ANIMATE_FROM_OVERVIEW   = 104;
28080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int ANIMATE_TO_OVERVIEW     = 105;
28090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int OPEN_TAB_AND_SHOW       = 106;
28100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int CHECK_MEMORY            = 107;
28110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int RELEASE_WAKELOCK        = 108;
28120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Private handler for handling javascript and saving passwords
28140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Handler mHandler = new Handler() {
28150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void handleMessage(Message msg) {
28170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            switch (msg.what) {
28180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case ANIMATE_FROM_OVERVIEW:
28190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    final HashMap map = (HashMap) msg.obj;
28200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    animateFromTabOverview((AnimatingView) map.get("view"),
28210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            msg.arg1 == 1, (Message) map.get("msg"));
28220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case ANIMATE_TO_OVERVIEW:
28250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    animateToTabOverview(msg.arg1, msg.arg2 == 1,
28260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            (AnimatingView) msg.obj);
28270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case OPEN_TAB_AND_SHOW:
28300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Decrement mAnimationCount before openTabAndShow because
28310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // the method relies on the value being 0 to start the next
28320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // animation.
28330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mAnimationCount--;
2834f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    openTabAndShow((String) msg.obj, null, false, null);
28350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case FOCUS_NODE_HREF:
28380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String url = (String) msg.getData().get("url");
28390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url == null || url.length() == 0) {
28400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
28410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    HashMap focusNodeMap = (HashMap) msg.obj;
28430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebView view = (WebView) focusNodeMap.get("webview");
28440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Only apply the action if the top window did not change.
28450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (getTopWindow() != view) {
28460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        break;
28470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    switch (msg.arg1) {
28490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_context_menu_id:
28500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.view_image_context_menu_id:
28510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            loadURL(getTopWindow(), url);
28520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.open_newtab_context_menu_id:
2854c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            final TabControl.Tab parent = mTabControl
2855c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                    .getCurrentTab();
2856c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            final TabControl.Tab newTab = openTab(url);
2857c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            if (newTab != parent) {
2858c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                                parent.addChildTab(newTab);
2859c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                            }
28600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.bookmark_context_menu_id:
28620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Intent intent = new Intent(BrowserActivity.this,
28630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    AddBookmarkPage.class);
28640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            intent.putExtra("url", url);
28650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            startActivity(intent);
28660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.share_link_context_menu_id:
28680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Browser.sendString(BrowserActivity.this, url);
28690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.copy_link_context_menu_id:
28710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            copy(url);
28720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.save_link_context_menu_id:
28740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        case R.id.download_context_menu_id:
28750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            onDownloadStartNoStream(url, null, null, null, -1);
28760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            break;
28770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
28780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case LOAD_URL:
28810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    loadURL(getTopWindow(), (String) msg.obj);
28820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case STOP_LOAD:
28850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    stopLoading();
28860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CANCEL_CREDS_REQUEST:
28890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    resumeAfterCredentials();
28900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
28920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case CHECK_MEMORY:
28930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // reschedule to check memory condition
28940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mHandler.removeMessages(CHECK_MEMORY);
28950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mHandler.sendMessageDelayed(mHandler.obtainMessage
28960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            (CHECK_MEMORY), CHECK_MEMORY_INTERVAL);
28970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    checkMemory();
28980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
28990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                case RELEASE_WAKELOCK:
29010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
29020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
29030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
29040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    break;
29050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
29080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // -------------------------------------------------------------------------
29100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebViewClient implementation.
29110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //-------------------------------------------------------------------------
29120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Use in overrideUrlLoading
29140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
29150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
29160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
29170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
29180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebViewClient getWebViewClient() {
29200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebViewClient;
29210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateIcon(String url, Bitmap icon) {
29240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (icon != null) {
29250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
29260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    url, icon);
29270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
29280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        setFavicon(icon);
29290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
29300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebViewClient mWebViewClient = new WebViewClient() {
29320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
29330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageStarted(WebView view, String url, Bitmap favicon) {
29340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetLockIcon(url);
29350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(url, null);
29360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Call updateIcon instead of setFavicon so the bookmark
29370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // database can be updated.
29380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateIcon(url, favicon);
29390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSettings.isTracing() == true) {
29410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // FIXME: we should save the trace file somewhere other than data.
29420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // I can't use "/tmp" as it competes for system memory.
29430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                File file = getDir("browserTrace", 0);
29440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String baseDir = file.getPath();
29450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (!baseDir.endsWith(File.separator)) baseDir += File.separator;
29460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String host;
29470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
29480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    WebAddress uri = new WebAddress(url);
29490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    host = uri.mHost;
29500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (android.net.ParseException ex) {
29510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    host = "unknown_host";
29520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                host = host.replace('.', '_');
29540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                baseDir = baseDir + host;
29550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                file = new File(baseDir+".data");
29560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (file.exists() == true) {
29570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    file.delete();
29580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                file = new File(baseDir+".key");
29600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (file.exists() == true) {
29610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    file.delete();
29620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = true;
29640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Debug.startMethodTracing(baseDir, 8 * 1024 * 1024);
29650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
29680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (false) {
29690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mStart = SystemClock.uptimeMillis();
29700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mProcessStart = Process.getElapsedCpuTime();
29710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
29720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
29730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
29740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mUserStart = sysCpu[0] + sysCpu[1];
29750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mSystemStart = sysCpu[2];
29760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIdleStart = sysCpu[3];
29770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
29780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
29790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mUiStart = SystemClock.currentThreadTimeMillis();
29800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mPageStarted) {
29830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = true;
29847bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // if onResume() has been called, resumeWebViewTimers() does
29857bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // nothing.
29867bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                resumeWebViewTimers();
29870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
29880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // reset sync timer to avoid sync starts during loading a page
29900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            CookieSyncManager.getInstance().resetSync();
29910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
29920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mInLoad = true;
29930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateInLoadMenuItems();
29940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mIsNetworkUp) {
29950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if ( mAlertDialog == null) {
29960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mAlertDialog = new AlertDialog.Builder(BrowserActivity.this)
29970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.loadSuspendedTitle)
29980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.loadSuspended)
29990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
30000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
30010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (view != null) {
30030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    view.setNetworkAvailable(false);
30040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
30050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
30060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // schedule to check memory condition
30080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.sendMessageDelayed(mHandler.obtainMessage(CHECK_MEMORY),
30090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CHECK_MEMORY_INTERVAL);
30100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
30110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
30130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onPageFinished(WebView view, String url) {
30140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Reset the title and icon in case we stopped a provisional
30150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // load.
30160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndIcon(view);
30170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
30180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Update the lock icon image only once we are done loading
30190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateLockIconImage(mLockIconType);
30200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
3021b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins            // If this is a bookmarked site, add a screenshot to the database.
3022b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins            // FIXME: When should we update?  Every time?
3023b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins            if (url != null) {
3024b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                // copied from BrowserBookmarksAdapter
3025b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                int query = url.indexOf('?');
3026b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                String noQuery = url;
3027b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                if (query != -1) {
3028b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                    noQuery = url.substring(0, query);
3029b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                }
3030b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                String URL = noQuery + '?';
3031b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                String[] selArgs = new String[] { noQuery, URL };
3032b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                final String where = "(url == ? OR url GLOB ? || '*') AND bookmark == 1";
3033b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                final String[] projection = new String[] { Browser.BookmarkColumns._ID };
3034b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                ContentResolver cr = getContentResolver();
3035b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                final Cursor c = cr.query(Browser.BOOKMARKS_URI, projection, where, selArgs, null);
3036b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                boolean succeed = c.moveToFirst();
3037b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                ContentValues values = null;
3038b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                while (succeed) {
3039b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                    if (values == null) {
3040b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        final ByteArrayOutputStream os = new ByteArrayOutputStream();
3041b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        Picture thumbnail = view.capturePicture();
3042b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        // Height was arbitrarily chosen
3043b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        Bitmap bm = Bitmap.createBitmap(100, 100,
3044b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                                Bitmap.Config.ARGB_4444);
3045b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        Canvas canvas = new Canvas(bm);
3046b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        // Scale chosen to be about one third, since we want
3047b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        // roughly three rows/columns for bookmark page
3048b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        canvas.scale(.3f, .3f);
3049b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        thumbnail.draw(canvas);
3050b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        bm.compress(Bitmap.CompressFormat.PNG, 100, os);
3051b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        values = new ContentValues();
3052b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                        values.put(Browser.BookmarkColumns.THUMBNAIL,
3053b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                                os.toByteArray());
3054b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                    }
3055b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                    cr.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
3056b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                            c.getInt(0)), values, null, null);
3057b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                    succeed = c.moveToNext();
3058b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                }
3059b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins                c.close();
3060b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins            }
3061b6b7f9ef3b4ed220063f555d8b7c205210a61a04Leon Scroggins
30620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Performance probe
3063cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project            if (false) {
30640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                long[] sysCpu = new long[7];
30650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
30660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        sysCpu, null)) {
30670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String uiInfo = "UI thread used "
30680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.currentThreadTimeMillis() - mUiStart)
30690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms";
307031a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
30710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, uiInfo);
30720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    //The string that gets written to the log
30740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String performanceString = "It took total "
30750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (SystemClock.uptimeMillis() - mStart)
30760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms clock time to load the page."
30770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + "\nbrowser process used "
30780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (Process.getElapsedCpuTime() - mProcessStart)
30790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, user processes used "
30800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
30810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, kernel used "
30820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[2] - mSystemStart) * 10
30830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
30840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + " ms and irq took "
30850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
30860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            * 10 + " ms, " + uiInfo;
308731a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
30880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
30890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
30900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (url != null) {
30910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // strip the url to maintain consistency
30920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        String newUrl = new String(url);
30930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (newUrl.startsWith("http://www.")) {
30940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(11);
30950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("http://")) {
30960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(7);
30970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://www.")) {
30980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(12);
30990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else if (newUrl.startsWith("https://")) {
31000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            newUrl = newUrl.substring(8);
31010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
310231a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGD_ENABLED) {
31030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.d(LOGTAG, newUrl + " loaded");
31040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        /*
31060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (sWhiteList.contains(newUrl)) {
31070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // The string that gets pushed to the statistcs
31080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // service
31090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            performanceString = performanceString
31100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nWebpage: "
31110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + newUrl
31120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + "\nCarrier: "
31130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    + android.os.SystemProperties
31140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            .get("gsm.sim.operator.alpha");
31150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (mWebView != null
31160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext() != null
31170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    && mWebView.getContext().getSystemService(
31180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Context.CONNECTIVITY_SERVICE) != null) {
31190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                ConnectivityManager cManager =
31200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (ConnectivityManager) mWebView
31210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getContext().getSystemService(
31220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        Context.CONNECTIVITY_SERVICE);
31230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                NetworkInfo nInfo = cManager
31240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getActiveNetworkInfo();
31250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                if (nInfo != null) {
31260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString = performanceString
31270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + "\nNetwork Type: "
31280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            + nInfo.getType().toString();
31290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
31300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
31310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Checkin.logEvent(mResolver,
31320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Checkin.Events.Tag.WEBPAGE_LOAD,
31330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    performanceString);
31340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.w(LOGTAG, "pushed to the statistics service");
31350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
31360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        */
31370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             }
31400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mInTrace) {
31420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mInTrace = false;
31430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Debug.stopMethodTracing();
31440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mPageStarted) {
31470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mPageStarted = false;
31487bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // pauseWebViewTimers() will do nothing and return false if
31497bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                // onPause() is not called yet.
31507bfa63b55644fbf2da1fe6a24b3be0267529202cMike Reed                if (pauseWebViewTimers()) {
31510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (mWakeLock.isHeld()) {
31520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mHandler.removeMessages(RELEASE_WAKELOCK);
31530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mWakeLock.release();
31540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
31550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mHandler.removeMessages(CHECK_MEMORY);
31590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            checkMemory();
31600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
31610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // return true if want to hijack the url to let another app to handle it
31630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
31640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideUrlLoading(WebView view, String url) {
31650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith(SCHEME_WTAI)) {
31660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/mc;number
31670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
31680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_MC)) {
31690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Intent intent = new Intent(Intent.ACTION_VIEW,
31700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Uri.parse(WebView.SCHEME_TEL +
31710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            url.substring(SCHEME_WTAI_MC.length())));
31720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    startActivity(intent);
31730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
31740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/sd;dtmf
31760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // dtmf=string(dialstring)
31770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_SD)) {
31780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
31790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // only send when there is active voice connection
31800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
31810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // wtai://wp/ap;number;name
31830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // number=string(phone-number)
31840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // name=string
31850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (url.startsWith(SCHEME_WTAI_AP)) {
31860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // TODO
31870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return false;
31880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
31890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
31900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
31919918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // The "about:" schemes are internal to the browser; don't
31929918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // want these to be dispatched to other apps.
31939918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            if (url.startsWith("about:")) {
31949918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                return false;
31959918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            }
31969918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn
31979918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            Intent intent;
31989918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn
31999918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // perform generic parsing of the URI to turn it into an Intent.
32000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
32019918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
32029918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            } catch (URISyntaxException ex) {
32039918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn                Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
32040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
32050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
32060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32075b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            // check whether the intent can be resolved. If not, we will see
32085b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            // whether we can download it from the Market.
32095b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            if (getPackageManager().resolveActivity(intent, 0) == null) {
32105b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                String packagename = intent.getPackage();
32115b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                if (packagename != null) {
32125b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    intent = new Intent(Intent.ACTION_VIEW, Uri
32135b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                            .parse("market://search?q=pname:" + packagename));
32145b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
32155b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    startActivity(intent);
32165b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    return true;
32175b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                } else {
32185b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                    return false;
32195b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba                }
32205b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba            }
32215b078b5b8f166a14ab88137e478f868959c5befaGrace Kloba
32229918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // sanitize the Intent, ensuring web pages can not bypass browser
32239918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            // security (only access to BROWSABLE activities).
32240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.addCategory(Intent.CATEGORY_BROWSABLE);
32259918943559193e3e047a1c18442e2cdb0fe22b15Dianne Hackborn            intent.setComponent(null);
32260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
32270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (startActivityIfNeeded(intent, -1)) {
32280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return true;
32290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
32300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (ActivityNotFoundException ex) {
32310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // ignore the error. If no application can handle the URL,
32320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // eg about:blank, assume the browser can handle it.
32330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
32340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
32360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                openTab(url);
32370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                closeOptionsMenu();
32380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
32390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
32400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return false;
32420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
32450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Updates the lock icon. This method is called when we discover another
32460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * resource to be loaded for this page (for example, javascript). While
32470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we update the icon type, we do not update the lock icon itself until
32480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * we are done loading, it is slightly more secure this way.
32490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
32500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
32510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onLoadResource(WebView view, String url) {
32520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url != null && url.length() > 0) {
32530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // It is only if the page claims to be secure
32540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // that we may have to update the lock:
32550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mLockIconType == LOCK_ICON_SECURE) {
32560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // If NOT a 'safe' url, change the lock to mixed content!
32570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url) || URLUtil.isAboutUrl(url))) {
32580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mLockIconType = LOCK_ICON_MIXED;
325931a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                        if (LOGV_ENABLED) {
32600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            Log.v(LOGTAG, "BrowserActivity.updateLockIcon:" +
32610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                  " updated lock icon to " + mLockIconType + " due to " + url);
32620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
32630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
32640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
32650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
32660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
32680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
32690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show the dialog, asking the user if they would like to continue after
32700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * an excessive number of HTTP redirects.
32710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
32720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
32730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onTooManyRedirects(WebView view, final Message cancelMsg,
32740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final Message continueMsg) {
32750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
32760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameRedirect)
32770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrame307Post)
32780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
32790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
32800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        continueMsg.sendToTarget();
32810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
32820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
32830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
32840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
32850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
32860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
32870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
32880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        cancelMsg.sendToTarget();
32890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
32900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
32910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
32920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
329337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        // Container class for the next error dialog that needs to be
329437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        // displayed.
329537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        class ErrorDialog {
329637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final int mTitle;
329737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final String mDescription;
329837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            public final int mError;
329937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            ErrorDialog(int title, String desc, int error) {
330037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mTitle = title;
330137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mDescription = desc;
330237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mError = error;
330337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
330437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        };
330537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
330637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void processNextError() {
330737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors == null) {
330837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                return;
330937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
331037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            // The first one is currently displayed so just remove it.
331137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            mQueuedErrors.removeFirst();
331237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors.size() == 0) {
331337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mQueuedErrors = null;
331437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                return;
331537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
331637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            showError(mQueuedErrors.getFirst());
331737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
331837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
331937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private DialogInterface.OnDismissListener mDialogListener =
332037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                new DialogInterface.OnDismissListener() {
332137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    public void onDismiss(DialogInterface d) {
332237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                        processNextError();
332337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    }
332437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                };
332537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private LinkedList<ErrorDialog> mQueuedErrors;
332637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
332737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void queueError(int err, String desc) {
332837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors == null) {
332937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                mQueuedErrors = new LinkedList<ErrorDialog>();
333037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
333137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            for (ErrorDialog d : mQueuedErrors) {
333237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                if (d.mError == err) {
333337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    // Already saw a similar error, ignore the new one.
333437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    return;
333537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                }
333637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
333737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            ErrorDialog errDialog = new ErrorDialog(
333837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    err == EventHandler.FILE_NOT_FOUND_ERROR ?
333937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    R.string.browserFrameFileErrorLabel :
334037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    R.string.browserFrameNetworkErrorLabel,
334137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    desc, err);
334237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            mQueuedErrors.addLast(errDialog);
334337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
334437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            // Show the dialog now if the queue was empty.
334537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            if (mQueuedErrors.size() == 1) {
334637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                showError(errDialog);
334737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            }
334837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
334937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
335037911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        private void showError(ErrorDialog errDialog) {
335137911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            AlertDialog d = new AlertDialog.Builder(BrowserActivity.this)
335237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setTitle(errDialog.mTitle)
335337911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setMessage(errDialog.mDescription)
335437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .setPositiveButton(R.string.ok, null)
335537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    .create();
335637911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            d.setOnDismissListener(mDialogListener);
335737911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            d.show();
335837911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott        }
335937911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott
33600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
33610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Show a dialog informing the user of the network error reported by
33620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * WebCore.
33630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
33640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
33650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedError(WebView view, int errorCode,
33660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String description, String failingUrl) {
33670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (errorCode != EventHandler.ERROR_LOOKUP &&
33680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.ERROR_CONNECT &&
33690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.ERROR_BAD_URL &&
33700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.ERROR_UNSUPPORTED_SCHEME &&
33710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    errorCode != EventHandler.FILE_ERROR) {
337237911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                queueError(errorCode, description);
33730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
337437911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott            Log.e(LOGTAG, "onReceivedError " + errorCode + " " + failingUrl
337537911c78a0647567fd9fa49125e7de37455b2d5aPatrick Scott                    + " " + description);
33760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We need to reset the title after an error.
33780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            resetTitleAndRevertLockIcon();
33790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
33800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
33810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
33820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Check with the user if it is ok to resend POST data as the page they
33830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * are trying to navigate to is the result of a POST.
33840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
33850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
33860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onFormResubmission(WebView view, final Message dontResend,
33870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                       final Message resend) {
33880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(BrowserActivity.this)
33890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.browserFrameFormResubmitLabel)
33900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(R.string.browserFrameFormResubmitMessage)
33910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
33920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
33930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        resend.sendToTarget();
33940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
33950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
33960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog, int which) {
33970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
33980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
33990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new OnCancelListener() {
34000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
34010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        dontResend.sendToTarget();
34020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }})
34030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
34040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
34070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Insert the url into the visited history database.
34080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param url The url to be inserted.
34090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param isReload True if this url is being reloaded.
34100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * FIXME: Not sure what to do when reloading the page.
34110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
34120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
34130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void doUpdateVisitedHistory(WebView view, String url,
34140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                boolean isReload) {
34150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.regionMatches(true, 0, "about:", 0, 6)) {
34160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
34170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
34180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Browser.updateVisitedHistory(mResolver, url, true);
34190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebIconDatabase.getInstance().retainIconForPageUrl(url);
34200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
34210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
34230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Displays SSL error(s) dialog to the user.
34240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
34250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
34260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedSslError(
34270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final WebView view, final SslErrorHandler handler, final SslError error) {
34280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mSettings.showSecurityWarnings()) {
34300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LayoutInflater factory =
34310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LayoutInflater.from(BrowserActivity.this);
34320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final View warningsView =
34330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    factory.inflate(R.layout.ssl_warnings, null);
34340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final LinearLayout placeholder =
34350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
34360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_UNTRUSTED)) {
34380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
34390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
34400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
34410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_untrusted);
34420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
34430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
34440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_IDMISMATCH)) {
34460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
34470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
34480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
34490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_mismatch);
34500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
34510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
34520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_EXPIRED)) {
34540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
34550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
34560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
34570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_expired);
34580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
34590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
34600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (error.hasError(SslError.SSL_NOTYETVALID)) {
34620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    LinearLayout ll = (LinearLayout)factory
34630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .inflate(R.layout.ssl_warning, null);
34640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    ((TextView)ll.findViewById(R.id.warning))
34650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setText(R.string.ssl_not_yet_valid);
34660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    placeholder.addView(ll);
34670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
34680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
34690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
34700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.security_warning)
34710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
34720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setView(warningsView)
34730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.ssl_continue,
34740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
34750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
34760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.proceed();
34770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
34780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
34790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNeutralButton(R.string.view_certificate,
34800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
34810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
34820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    showSSLCertificateOnError(view, handler, error);
34830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
34840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
34850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.cancel,
34860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnClickListener() {
34870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onClick(DialogInterface dialog, int whichButton) {
34880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
34890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
34900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
34910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
34920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setOnCancelListener(
34930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            new DialogInterface.OnCancelListener() {
34940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                public void onCancel(DialogInterface dialog) {
34950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    handler.cancel();
34960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
34970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                }
34980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            })
34990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .show();
35000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
35010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed();
35020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        /**
35060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * Handles an HTTP authentication request.
35070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         *
35080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param handler The authentication handler
35090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param host The host
35100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         * @param realm The realm
35110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project         */
35120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedHttpAuthRequest(WebView view,
35140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final HttpAuthHandler handler, final String host, final String realm) {
35150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String username = null;
35160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String password = null;
35170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            boolean reuseHttpAuthUsernamePassword =
35190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.useHttpAuthUsernamePassword();
35200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (reuseHttpAuthUsernamePassword &&
35220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    (mTabControl.getCurrentWebView() != null)) {
35230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String[] credentials =
35240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mTabControl.getCurrentWebView()
35250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                .getHttpAuthUsernamePassword(host, realm);
35260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (credentials != null && credentials.length == 2) {
35270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    username = credentials[0];
35280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    password = credentials[1];
35290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
35300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (username != null && password != null) {
35330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                handler.proceed(username, password);
35340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
35350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                showHttpAuthentication(handler, host, realm, null, null, null, 0);
35360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
35410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mMenuIsDown) {
35420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // only check shortcut key when MENU is held
35430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return getWindow().isShortcutKey(event.getKeyCode(), event);
35440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
35450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
35460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
35510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (view != mTabControl.getCurrentTopWebView()) {
35520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
35530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (event.isDown()) {
35550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyDown(event.getKeyCode(), event);
35560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
35570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserActivity.this.onKeyUp(event.getKeyCode(), event);
35580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
35610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
35630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // WebChromeClient implementation
35640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    //--------------------------------------------------------------------------
35650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ WebChromeClient getWebChromeClient() {
35670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mWebChromeClient;
35680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
35690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
35710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Helper method to create a new tab or sub window.
35720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private void createWindow(final boolean dialog, final Message msg) {
35730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog) {
35740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabControl.createSubWindow();
35750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab t = mTabControl.getCurrentTab();
35760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                attachSubWindow(t);
35770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
35780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
35790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(t.getSubWebView());
35800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg.sendToTarget();
35810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
35820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final TabControl.Tab parent = mTabControl.getCurrentTab();
35830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // openTabAndShow will dispatch the message after creating the
35840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // new WebView. This will prevent another request from coming
35850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // in during the animation.
35861536e7307cd5ec7d71f9b5a40972c58846aee554Patrick Scott                final TabControl.Tab newTab =
35871536e7307cd5ec7d71f9b5a40972c58846aee554Patrick Scott                        openTabAndShow(EMPTY_URL_DATA, msg, false, null);
3588c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                if (newTab != parent) {
3589c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                    parent.addChildTab(newTab);
3590c9181841c7ed6b9f7dfc953eab8dc7ba1047022cGrace Kloba                }
35910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WebView.WebViewTransport transport =
35920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        (WebView.WebViewTransport) msg.obj;
35930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                transport.setWebView(mTabControl.getCurrentWebView());
35940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
35950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
35960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
35970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
35980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public boolean onCreateWindow(WebView view, final boolean dialog,
35990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                final boolean userGesture, final Message resultMsg) {
36000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Ignore these requests during tab animations or if the tab
36010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // overview is showing.
36020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAnimationCount > 0 || mTabOverview != null) {
36030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
36040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if we can't create any more tabs or sub windows.
36060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (dialog && mTabControl.getCurrentSubWindow() != null) {
36070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
36080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_subwindows_dialog_title)
36090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
36100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_subwindows_dialog_message)
36110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
36120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
36130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
36140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (mTabControl.getTabCount() >= TabControl.MAX_TABS) {
36150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new AlertDialog.Builder(BrowserActivity.this)
36160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.too_many_windows_dialog_title)
36170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setIcon(android.R.drawable.ic_dialog_alert)
36180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.too_many_windows_dialog_message)
36190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
36200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
36210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return false;
36220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Short-circuit if this was a user gesture.
36250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (userGesture) {
36260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // createWindow will call openTabAndShow for new Windows and
36270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // that will call tabPicker which will increment
36280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // mAnimationCount.
36290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                createWindow(dialog, resultMsg);
36300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return true;
36310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Allow the popup and create the appropriate window.
36340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener allowListener =
36350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
36360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d,
36370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                int which) {
36380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // Same comment as above for setting
36390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // mAnimationCount.
36400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            createWindow(dialog, resultMsg);
36410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // Since we incremented mAnimationCount while the
36420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // dialog was up, we have to decrement it here.
36430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mAnimationCount--;
36440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
36450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
36460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Block the popup by returning a null WebView.
36480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog.OnClickListener blockListener =
36490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.OnClickListener() {
36500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onClick(DialogInterface d, int which) {
36510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            resultMsg.sendToTarget();
36520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // We are not going to trigger an animation so
36530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // unblock keys and animation requests.
36540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mAnimationCount--;
36550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
36560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    };
36570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Build a confirmation dialog to display to the user.
36590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final AlertDialog d =
36600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    new AlertDialog.Builder(BrowserActivity.this)
36610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setTitle(R.string.attention)
36620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
36630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setMessage(R.string.popup_window_attempt)
36640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setPositiveButton(R.string.allow, allowListener)
36650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setNegativeButton(R.string.block, blockListener)
36660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .setCancelable(false)
36670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    .create();
36680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Show the confirmation dialog.
36700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d.show();
36710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We want to increment mAnimationCount here to prevent a
36720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // potential race condition. If the user allows a pop-up from a
36730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // site and that pop-up then triggers another pop-up, it is
36740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // possible to get the BACK key between here and when the dialog
36750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // appears.
36760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mAnimationCount++;
36770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return true;
36780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
36810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onCloseWindow(WebView window) {
36820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final int currentIndex = mTabControl.getCurrentIndex();
36830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab parent =
36840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    mTabControl.getCurrentTab().getParentTab();
36850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (parent != null) {
36860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // JavaScript can only close popup window.
36870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                switchTabs(currentIndex, mTabControl.getTabIndex(parent), true);
36880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
36890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
36900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
36910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
36920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onProgressChanged(WebView view, int newProgress) {
36930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Block progress updates to the title bar while the tab overview
36940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // is animating or being displayed.
36950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAnimationCount == 0 && mTabOverview == null) {
369681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                if (CUSTOM_BROWSER_BAR) {
369781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                    mTitleBar.setProgress(newProgress);
369881db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                } else {
369981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                    getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
370081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                            newProgress * 100);
370181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
370281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                }
37030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (newProgress == 100) {
37060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // onProgressChanged() is called for sub-frame too while
37070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // onPageFinished() is only called for the main frame. sync
37080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // cookie and cache promptly here.
37090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CookieSyncManager.getInstance().sync();
3710cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                if (mInLoad) {
3711cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    mInLoad = false;
3712cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    updateInLoadMenuItems();
3713cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
3714cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project            } else {
3715cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // onPageFinished may have already been called but a subframe
3716cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // is still loading and updating the progress. Reset mInLoad
3717cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                // and update the menu items.
3718cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                if (!mInLoad) {
3719cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    mInLoad = true;
3720cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                    updateInLoadMenuItems();
3721cb9a0bbc3a00a044fbfdabda920d3be80b0747f0The Android Open Source Project                }
37220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
37260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedTitle(WebView view, String title) {
3727598c9ccf8641e0e4563bba2fd5613bcb4de766ecPatrick Scott            String url = view.getUrl();
37280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // here, if url is null, we want to reset the title
37300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            setUrlTitle(url, title);
37310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url == null ||
37330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url.length() >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
37340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return;
37350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
3736fce182bff7713a12714018327f6da9500011ab17Leon Scroggins            // See if we can find the current url in our history database and
3737fce182bff7713a12714018327f6da9500011ab17Leon Scroggins            // add the new title to it.
37380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (url.startsWith("http://www.")) {
37390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(11);
37400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else if (url.startsWith("http://")) {
37410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = url.substring(4);
37420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            try {
37440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = "%" + url;
37450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String [] selArgs = new String[] { url };
37460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                String where = Browser.BookmarkColumns.URL + " LIKE ? AND "
37480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        + Browser.BookmarkColumns.BOOKMARK + " = 0";
37490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
37500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Browser.HISTORY_PROJECTION, where, selArgs, null);
37510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (c.moveToFirst()) {
37520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Current implementation of database only has one entry per
37530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // url.
3754fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    ContentValues map = new ContentValues();
3755fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    map.put(Browser.BookmarkColumns.TITLE, title);
3756fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                    mResolver.update(Browser.BOOKMARKS_URI, map,
3757fce182bff7713a12714018327f6da9500011ab17Leon Scroggins                            "_id = " + c.getInt(0), null);
37580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
37590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                c.close();
37600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (IllegalStateException e) {
37610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "BrowserActivity onReceived title", e);
37620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } catch (SQLiteException ex) {
37630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.e(LOGTAG, "onReceivedTitle() caught SQLiteException: ", ex);
37640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
37650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
37660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
37670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
37680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onReceivedIcon(WebView view, Bitmap icon) {
37690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            updateIcon(view.getUrl(), icon);
37700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
3771092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch
3772adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        @Override
3773adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        public void onShowCustomView(View view) {
3774adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            if (mCustomView != null)
3775adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                return;
3776adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3777adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Add the custom view to its container.
3778adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer.addView(view, COVER_SCREEN_GRAVITY_CENTER);
3779adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomView = view;
3780adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Save the menu state and set it to empty while the custom
3781adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // view is showing.
3782adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mOldMenuState = mMenuState;
3783adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mMenuState = EMPTY_MENU;
3784adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Finally show the custom view container.
3785adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu             mCustomViewContainer.setVisibility(View.VISIBLE);
3786adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu             mCustomViewContainer.bringToFront();
3787adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        }
3788adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3789adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        @Override
3790adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        public void onHideCustomView() {
3791adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            if (mCustomView == null)
3792adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                return;
3793adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3794adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Remove the custom view from its container.
3795adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer.removeView(mCustomView);
3796adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomView = null;
3797adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            // Reset the old menu state.
3798adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mMenuState = mOldMenuState;
3799adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mOldMenuState = EMPTY_MENU;
3800adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu            mCustomViewContainer.setVisibility(View.GONE);
3801adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu        }
3802adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu
3803092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        /**
3804092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * The origin has exceeded it's database quota.
3805092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param url the URL that exceeded the quota
3806092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param databaseIdentifier the identifier of the database on
3807092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         *     which the transaction that caused the quota overflow was run
3808092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param currentQuota the current quota for the origin.
3809092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         * @param quotaUpdater The callback to run when a decision to allow or
3810092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         *     deny quota has been made. Don't forget to call this!
3811092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch         */
3812092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        @Override
3813092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        public void onExceededDatabaseQuota(String url,
3814092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch            String databaseIdentifier, long currentQuota,
3815092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch            WebStorage.QuotaUpdater quotaUpdater) {
3816092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch            if(LOGV_ENABLED) {
3817092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                Log.v(LOGTAG,
3818092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      "BrowserActivity received onExceededDatabaseQuota for "
3819092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      + url +
3820092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      ":"
3821092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      + databaseIdentifier +
3822092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      "(current quota: "
3823092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      + currentQuota +
3824092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch                      ")");
3825092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch            }
382678a98e459323f938e97789a6131beddbebb459ceNicolas Roard            mWebStorageQuotaUpdater = quotaUpdater;
382778a98e459323f938e97789a6131beddbebb459ceNicolas Roard            String DIALOG_PACKAGE = "com.android.browser";
382878a98e459323f938e97789a6131beddbebb459ceNicolas Roard            String DIALOG_CLASS = DIALOG_PACKAGE + ".PermissionDialog";
382978a98e459323f938e97789a6131beddbebb459ceNicolas Roard            Intent intent = new Intent();
383078a98e459323f938e97789a6131beddbebb459ceNicolas Roard            intent.setClassName(DIALOG_PACKAGE, DIALOG_CLASS);
383178a98e459323f938e97789a6131beddbebb459ceNicolas Roard            intent.putExtra(PermissionDialog.PARAM_ORIGIN, url);
383278a98e459323f938e97789a6131beddbebb459ceNicolas Roard            intent.putExtra(PermissionDialog.PARAM_QUOTA, currentQuota);
383378a98e459323f938e97789a6131beddbebb459ceNicolas Roard            startActivityForResult(intent, WEBSTORAGE_QUOTA_DIALOG);
3834092dd5d22d7f2ee0efcc68bd6e5a3afd1ea98953Ben Murdoch        }
38357db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch
38367db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        /* Adds a JavaScript error message to the system log.
38377db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param message The error message to report.
38387db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param lineNumber The line number of the error.
38397db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         * @param sourceID The name of the source file that caused the error.
38407db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch         */
38417db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        @Override
38427db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        public void addMessageToConsole(String message, int lineNumber, String sourceID) {
38437db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch            Log.w(LOGTAG, "Console: " + message + " (" + sourceID + ":" + lineNumber + ")");
38447db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch        }
38457db26347577132b8c4def47ccd410e7b9d0821bbBen Murdoch
38460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
38470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
38490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, or that
38500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the data should be streamed if a streaming viewer is available.
38510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
38520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
38530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
38540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
38550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
38560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
38570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onDownloadStart(String url, String userAgent,
38580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
38590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we're dealing wih A/V content that's not explicitly marked
38600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //     for download, check if it's streamable.
38610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentDisposition == null
38620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        || !contentDisposition.regionMatches(true, 0, "attachment", 0, 10)) {
38630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // query the package manager to see if there's a registered handler
38640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            //     that matches.
38650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW);
38660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.setDataAndType(Uri.parse(url), mimetype);
38670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (getPackageManager().resolveActivity(intent,
38680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        PackageManager.MATCH_DEFAULT_ONLY) != null) {
38690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // someone knows how to handle this mime type with this scheme, don't download.
38700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                try {
38710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    startActivity(intent);
38720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    return;
38730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } catch (ActivityNotFoundException ex) {
387431a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort                    if (LOGD_ENABLED) {
38750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        Log.d(LOGTAG, "activity not found for " + mimetype
38760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                + " over " + Uri.parse(url).getScheme(), ex);
38770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
38780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Best behavior is to fall back to a download in this case
38790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
38800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
38810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
38820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
38830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
38840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
38860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Notify the host application a download should be done, even if there
38870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * is a streaming viewer available for thise type.
38880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param url The full url to the content that should be downloaded
38890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentDisposition Content-disposition http header, if
38900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                           present.
38910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param mimetype The mimetype of the content reported by the server
38920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param contentLength The file size reported by the server
38930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
38940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package */ void onDownloadStartNoStream(String url, String userAgent,
38950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String contentDisposition, String mimetype, long contentLength) {
38960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
38970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String filename = URLUtil.guessFileName(url,
38980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                contentDisposition, mimetype);
38990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Check to see if we have an SDCard
39010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String status = Environment.getExternalStorageState();
39020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (!status.equals(Environment.MEDIA_MOUNTED)) {
39030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            int title;
39040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String msg;
39050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Check to see if the SDCard is busy, same as the music app
39070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (status.equals(Environment.MEDIA_SHARED)) {
39080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_sdcard_busy_dlg_msg);
39090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_sdcard_busy_dlg_title;
39100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
39110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
39120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                title = R.string.download_no_sdcard_dlg_title;
39130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
39160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(title)
39170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
39180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setMessage(msg)
39190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok, null)
39200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
39210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
39220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // java.net.URI is a lot stricter than KURL so we have to undo
39250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // KURL's percent-encoding and redo the encoding using java.net.URI.
39260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        URI uri = null;
39270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        try {
39280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Undo the percent-encoding that KURL may have done.
39290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String newUrl = new String(URLUtil.decode(url.getBytes()));
39300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Parse the url into pieces
39310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            WebAddress w = new WebAddress(newUrl);
39320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String frag = null;
39330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String query = null;
39340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String path = w.mPath;
39350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Break the path into path, query, and fragment
39360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (path.length() > 0) {
39370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Strip the fragment
39380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                int idx = path.lastIndexOf('#');
39390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
39400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    frag = path.substring(idx + 1);
39410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
39420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
39430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                idx = path.lastIndexOf('?');
39440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (idx != -1) {
39450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query = path.substring(idx + 1);
39460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    path = path.substring(0, idx);
39470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
39480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
39490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
39500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    query, frag);
39510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } catch (Exception e) {
39520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
39530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
39540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // XXX: Have to use the old url since the cookies were stored using the
39570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // old percent-encoded url.
39580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String cookies = CookieManager.getInstance().getCookie(url);
39590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ContentValues values = new ContentValues();
39613dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_URI, uri.toString());
39623dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_COOKIE_DATA, cookies);
39633dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_USER_AGENT, userAgent);
39643dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_NOTIFICATION_PACKAGE,
39650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                getPackageName());
39663dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_NOTIFICATION_CLASS,
39670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class.getCanonicalName());
39683dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_VISIBILITY, Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
39693dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_MIME_TYPE, mimetype);
39703dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_FILE_NAME_HINT, filename);
39713dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru        values.put(Downloads.COLUMN_DESCRIPTION, uri.getHost());
39720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (contentLength > 0) {
39733dc09b269fe4af164371f7a8268a5554b32c1be2Jean-Baptiste Queru            values.put(Downloads.COLUMN_TOTAL_BYTES, contentLength);
39740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mimetype == null) {
39760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // We must have long pressed on a link or image to download it. We
39770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // are not sure of the mimetype in this case, so do a head request
39780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new FetchUrlMimeType(this).execute(values);
39790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
39800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final Uri contentUri =
39810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    getContentResolver().insert(Downloads.CONTENT_URI, values);
39820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            viewDownloads(contentUri);
39830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
39840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
39860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
39880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon. This method is called when we start a new load and
39890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * know the url to be loaded.
39900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
39910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon(String url) {
39920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
39930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        saveLockIcon();
39940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
39950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = LOCK_ICON_UNSECURE;
39960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (URLUtil.isHttpsUrl(url)) {
39970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mLockIconType = LOCK_ICON_SECURE;
399831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (LOGV_ENABLED) {
39990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
40000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                      " reset lock icon to " + mLockIconType);
40010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
40020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
40050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Resets the lock icon.  This method is called when the icon needs to be
40090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * reset but we do not know whether we are loading a secure or not secure
40100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * page.
40110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void resetLockIcon() {
40130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Save the lock-icon state (we revert to it if the load gets cancelled)
40140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        saveLockIcon();
40150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mLockIconType = LOCK_ICON_UNSECURE;
40170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
401831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort        if (LOGV_ENABLED) {
40190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
40200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                " reset lock icon to " + mLockIconType);
40210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        updateLockIconImage(LOCK_ICON_UNSECURE);
40240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Updates the lock-icon image in the title-bar.
40280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void updateLockIconImage(int lockIconType) {
40300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Drawable d = null;
40310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (lockIconType == LOCK_ICON_SECURE) {
40320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mSecLockIcon;
40330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (lockIconType == LOCK_ICON_MIXED) {
40340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            d = mMixLockIcon;
40350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // If the tab overview is animating or being shown, do not update the
40370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // lock icon.
40380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mAnimationCount == 0 && mTabOverview == null) {
403981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            if (CUSTOM_BROWSER_BAR) {
404081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                mTitleBar.setLock(d);
404181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            } else {
404281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, d);
404381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            }
40440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
40460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
40480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays a page-info dialog.
40490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show info about
40500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param fromShowSSLCertificateOnError The flag that indicates whether
40510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * this dialog was opened from the SSL-certificate-on-error dialog or
40520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * not. This is important, since we need to know whether to return to
40530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the parent dialog or simply dismiss.
40540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
40550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showPageInfo(final TabControl.Tab tab,
40560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                              final boolean fromShowSSLCertificateOnError) {
40570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LayoutInflater factory = LayoutInflater
40580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .from(this);
40590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View pageInfoView = factory.inflate(R.layout.page_info, null);
40610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view = tab.getWebView();
40630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = null;
40650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = null;
40660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (view == null) {
40680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = tab.getUrl();
40690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = tab.getTitle();
40700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (view == mTabControl.getCurrentWebView()) {
40710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             // Use the cached title and url if this is the current WebView
40720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mUrl;
40730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = mTitle;
40740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
40750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = view.getUrl();
40760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = view.getTitle();
40770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null) {
40800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = "";
40810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
40830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = "";
40840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
40850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
40870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
40880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoView = tab;
40900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoFromShowSSLCertificateOnError = new Boolean(fromShowSSLCertificateOnError);
40910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
40920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog.Builder alertDialogBuilder =
40930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
40940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
40950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setView(pageInfoView)
40960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setPositiveButton(
40970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.ok,
40980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
40990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
41000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
41010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
41020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
41030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
41040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
41060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
41070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
41080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
41090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
41100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
41110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
41120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
41130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
41140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                })
41150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setOnCancelListener(
41160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnCancelListener() {
41170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onCancel(DialogInterface dialog) {
41180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
41190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
41200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
41210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
41230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
41240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
41250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
41260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
41270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
41280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
41290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
41300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
41310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
41320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // if we have a main top-level page SSL certificate set or a certificate
41340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // error
41350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (fromShowSSLCertificateOnError ||
41360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (view != null && view.getCertificate() != null)) {
41370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // add a 'View Certificate' button
41380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            alertDialogBuilder.setNeutralButton(
41390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                R.string.view_certificate,
41400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new DialogInterface.OnClickListener() {
41410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    public void onClick(DialogInterface dialog,
41420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        int whichButton) {
41430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoDialog = null;
41440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoView = null;
41450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        mPageInfoFromShowSSLCertificateOnError = null;
41460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // if we came here from the SSL error dialog
41480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (fromShowSSLCertificateOnError) {
41490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // go back to the SSL error dialog
41500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            showSSLCertificateOnError(
41510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView,
41520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler,
41530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError);
41540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
41550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // otherwise, display the top-most certificate from
41560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            // the chain
41570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (view.getCertificate() != null) {
41580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showSSLCertificate(tab);
41590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
41600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
41610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
41620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                });
41630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mPageInfoDialog = alertDialogBuilder.show();
41660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
41670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project       /**
41690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the main top-level page SSL certificate dialog
41700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * (accessible from the Page-Info dialog).
41710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param tab The tab to show certificate for.
41720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
41730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificate(final TabControl.Tab tab) {
41740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
41750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                inflateCertificateView(tab.getWebView().getCertificate());
41760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
41770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
41780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
41790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
41810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
41830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
41840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LinearLayout ll = (LinearLayout) factory.inflate(
41860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_success, placeholder);
41870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView)ll.findViewById(R.id.success))
41880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(R.string.ssl_certificate_is_valid);
41890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
41900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateView = tab;
41910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateDialog =
41920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
41930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
41940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_secure)
41950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
41960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
41970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
41980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
41990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
42000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
42010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
42020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
42040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
42050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
42060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
42070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
42080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
42090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateDialog = null;
42100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateView = null;
42110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(tab, false);
42130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
42140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
42150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
42160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
42170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
42190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays the SSL error certificate dialog.
42200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param view The target web-view.
42210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param handler The SSL error handler responsible for cancelling the
42220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connection that resulted in an SSL error or proceeding per user request.
42230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param error The SSL error object.
42240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
42250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showSSLCertificateOnError(
42260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final WebView view, final SslErrorHandler handler, final SslError error) {
42270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View certificateView =
42290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            inflateCertificateView(error.getCertificate());
42300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificateView == null) {
42310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
42320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
42350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final LinearLayout placeholder =
42370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                (LinearLayout)certificateView.findViewById(R.id.placeholder);
42380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_UNTRUSTED)) {
42400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
42410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
42420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
42430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_untrusted);
42440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_IDMISMATCH)) {
42470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
42480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
42490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
42500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_mismatch);
42510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_EXPIRED)) {
42540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
42550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
42560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
42570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_expired);
42580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (error.hasError(SslError.SSL_NOTYETVALID)) {
42610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            LinearLayout ll = (LinearLayout)factory
42620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.ssl_warning, placeholder);
42630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView)ll.findViewById(R.id.warning))
42640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(R.string.ssl_not_yet_valid);
42650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
42660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorHandler = handler;
42680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorView = view;
42690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorError = error;
42700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mSSLCertificateOnErrorDialog =
42710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            new AlertDialog.Builder(this)
42720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(R.string.ssl_certificate).setIcon(
42730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    R.drawable.ic_dialog_browser_certificate_partially_secure)
42740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(certificateView)
42750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.ok,
42760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
42770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
42780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
42790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
42800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
42810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
42820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
42830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
42850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
42860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
42870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
42880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                 .setNeutralButton(R.string.page_info_view,
42890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
42900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
42910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
42920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
42930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // do not clear the dialog state: we will
42950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // need to show the dialog again once the
42960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                // user is done exploring the page-info details
42970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
42980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                showPageInfo(mTabControl.getTabFromView(view),
42990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        true);
43000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
43010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
43020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(
43030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnCancelListener() {
43040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onCancel(DialogInterface dialog) {
43050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorDialog = null;
43060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorView = null;
43070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorHandler = null;
43080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mSSLCertificateOnErrorError = null;
43090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mWebViewClient.onReceivedSslError(
43110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    view, handler, error);
43120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
43130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        })
43140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .show();
43150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
43160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
43180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Inflates the SSL certificate view (helper method).
43190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param certificate The SSL certificate.
43200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return The resultant certificate view with issued-to, issued-by,
43210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * issued-on, expires-on, and possibly other fields set.
43220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the input certificate is null, returns null.
43230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
43240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private View inflateCertificateView(SslCertificate certificate) {
43250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (certificate == null) {
43260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return null;
43270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
43280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
43300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        View certificateView = factory.inflate(
43320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            R.layout.ssl_certificate, null);
43330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued to:
43350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedTo = certificate.getIssuedTo();
43360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedTo != null) {
43370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_common))
43380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getCName());
43390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org))
43400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getOName());
43410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.to_org_unit))
43420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedTo.getUName());
43430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
43440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued by:
43460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        SslCertificate.DName issuedBy = certificate.getIssuedBy();
43470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (issuedBy != null) {
43480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_common))
43490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getCName());
43500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org))
43510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getOName());
43520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((TextView) certificateView.findViewById(R.id.by_org_unit))
43530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setText(issuedBy.getUName());
43540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
43550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // issued on:
43570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String issuedOn = reformatCertificateDate(
43580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotBefore());
43590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.issued_on))
43600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(issuedOn);
43610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // expires on:
43630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String expiresOn = reformatCertificateDate(
43640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            certificate.getValidNotAfter());
43650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((TextView) certificateView.findViewById(R.id.expires_on))
43660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            .setText(expiresOn);
43670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return certificateView;
43690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
43700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
43720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Re-formats the certificate date (Date.toString()) string to
43730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * a properly localized date string.
43740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Properly localized version of the certificate date string and
43750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * the original certificate date string if fails to localize.
43760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * If the original string is null, returns an empty string "".
43770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
43780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String reformatCertificateDate(String certificateDate) {
43790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      String reformattedDate = null;
43800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if (certificateDate != null) {
43820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          Date date = null;
43830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          try {
43840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = java.text.DateFormat.getInstance().parse(certificateDate);
43850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          } catch (ParseException e) {
43860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              date = null;
43870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
43880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          if (date != null) {
43900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project              reformattedDate =
43910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                  DateFormat.getDateFormat(this).format(date);
43920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          }
43930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
43940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return reformattedDate != null ? reformattedDate :
43960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project          (certificateDate != null ? certificateDate : "");
43970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
43980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
43990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
44000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Displays an http-authentication dialog.
44010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
44020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void showHttpAuthentication(final HttpAuthHandler handler,
44030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String host, final String realm, final String title,
44040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final String name, final String password, int focusId) {
44050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        LayoutInflater factory = LayoutInflater.from(this);
44060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final View v = factory
44070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .inflate(R.layout.http_authentication, null);
44080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (name != null) {
44090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
44100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (password != null) {
44120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
44130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String titleText = title;
44160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (titleText == null) {
44170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            titleText = getText(R.string.sign_in_to).toString().replace(
44180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    "%s1", host).replace("%s2", realm);
44190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthHandler = handler;
44220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AlertDialog dialog = new AlertDialog.Builder(this)
44230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setTitle(titleText)
44240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setIcon(android.R.drawable.ic_dialog_alert)
44250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setView(v)
44260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setPositiveButton(R.string.action,
44270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
44280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                             public void onClick(DialogInterface dialog,
44290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                     int whichButton) {
44300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String nm = ((EditText) v
44310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.username_edit))
44320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
44330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                String pw = ((EditText) v
44340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .findViewById(R.id.password_edit))
44350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        .getText().toString();
44360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.setHttpAuthUsernamePassword
44370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                        (host, realm, nm, pw);
44380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.proceed(nm, pw);
44390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
44400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
44410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
44420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setNegativeButton(R.string.cancel,
44430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        new DialogInterface.OnClickListener() {
44440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            public void onClick(DialogInterface dialog,
44450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    int whichButton) {
44460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                handler.cancel();
44470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                BrowserActivity.this.resetTitleAndRevertLockIcon();
44480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthenticationDialog = null;
44490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mHttpAuthHandler = null;
44500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }})
44510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .setOnCancelListener(new DialogInterface.OnCancelListener() {
44520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        public void onCancel(DialogInterface dialog) {
44530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            handler.cancel();
44540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            BrowserActivity.this.resetTitleAndRevertLockIcon();
44550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthenticationDialog = null;
44560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            mHttpAuthHandler = null;
44570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }})
44580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .create();
44590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the IME appear when the dialog is displayed if applicable.
44600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.getWindow().setSoftInputMode(
44610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
44620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        dialog.show();
44630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (focusId != 0) {
44640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            dialog.findViewById(focusId).requestFocus();
44650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
44660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            v.findViewById(R.id.username_edit).requestFocus();
44670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHttpAuthenticationDialog = dialog;
44690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
44700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public int getProgress() {
44720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
44730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
44740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return w.getProgress();
44750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
44760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return 100;
44770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
44790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
44810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Set HTTP authentication password.
44820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
44830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param host The host for the password
44840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param realm The realm for the password
44850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param username The username for the password. If it is null, it means
44860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *            password can't be saved.
44870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param password The password
44880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
44890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void setHttpAuthUsernamePassword(String host, String realm,
44900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String username,
44910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            String password) {
44920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
44930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
44940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setHttpAuthUsernamePassword(host, realm, username, password);
44950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
44960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
44970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
44980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
44990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * connectivity manager says net has come or gone... inform the user
45000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @param up true if net has come up, false if net has gone down
45010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
45020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    public void onNetworkToggle(boolean up) {
45030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (up == mIsNetworkUp) {
45040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
45050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else if (up) {
45060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = true;
45070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mAlertDialog != null) {
45080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog.cancel();
45090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = null;
45100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
45120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mIsNetworkUp = false;
45130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mInLoad && mAlertDialog == null) {
45140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mAlertDialog = new AlertDialog.Builder(this)
45150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setTitle(R.string.loadSuspendedTitle)
45160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setMessage(R.string.loadSuspended)
45170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .setPositiveButton(R.string.ok, null)
45180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        .show();
45190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView w = mTabControl.getCurrentWebView();
45220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (w != null) {
45230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            w.setNetworkAvailable(up);
45240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    @Override
45280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode,
45290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                    Intent intent) {
45300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        switch (requestCode) {
45310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            case COMBO_PAGE:
45320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (resultCode == RESULT_OK && intent != null) {
45330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    String data = intent.getAction();
45340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    Bundle extras = intent.getExtras();
45350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    if (extras != null && extras.getBoolean("new_window", false)) {
45360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        openTab(data);
45370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    } else {
45380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        final TabControl.Tab currentTab =
45390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                mTabControl.getCurrentTab();
45400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // If the Window overview is up and we are not in the
45410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // middle of an animation, animate away from it to the
45420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        // current tab.
45430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        if (mTabOverview != null && mAnimationCount == 0) {
4544ec7eb37292836652e096b5804877e803e2505136Grace Kloba                            sendAnimateFromOverview(currentTab, false,
4545ec7eb37292836652e096b5804877e803e2505136Grace Kloba                                    new UrlData(data), TAB_OVERVIEW_DELAY, null);
45460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        } else {
45470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            dismissSubWindow(currentTab);
45480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            if (data != null && data.length() != 0) {
45490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                getTopWindow().loadUrl(data);
45500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            }
45510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                        }
45520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    }
45530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
45540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
455578a98e459323f938e97789a6131beddbebb459ceNicolas Roard            case WEBSTORAGE_QUOTA_DIALOG:
455678a98e459323f938e97789a6131beddbebb459ceNicolas Roard                long currentQuota = 0;
455778a98e459323f938e97789a6131beddbebb459ceNicolas Roard                if (resultCode == RESULT_OK && intent != null) {
455878a98e459323f938e97789a6131beddbebb459ceNicolas Roard                    currentQuota = intent.getLongExtra(
455978a98e459323f938e97789a6131beddbebb459ceNicolas Roard                        PermissionDialog.PARAM_QUOTA, currentQuota);
456078a98e459323f938e97789a6131beddbebb459ceNicolas Roard                }
456178a98e459323f938e97789a6131beddbebb459ceNicolas Roard                mWebStorageQuotaUpdater.updateQuota(currentQuota);
456278a98e459323f938e97789a6131beddbebb459ceNicolas Roard                break;
45630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            default:
45640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                break;
45650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
45660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        getTopWindow().requestFocus();
45670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*
45700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * This method is called as a result of the user selecting the options
45710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * menu to see the download window, or when a download changes state. It
45720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * shows the download window ontop of the current window.
45730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
45740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ void viewDownloads(Uri downloadRecord) {
45750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
45760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                BrowserDownloadPage.class);
45770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.setData(downloadRecord);
45780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, this.DOWNLOAD_PAGE);
45790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
45810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
45830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Handle results from Tab Switcher mTabOverview tool
45840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
45850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private class TabListener implements ImageGrid.Listener {
45860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void remove(int position) {
45870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Note: Remove is not enabled if we have only one tab.
458831a6d1cb63a513712bad717a6239919fd5428fd1Dave Bort            if (DEBUG && mTabControl.getTabCount() == 1) {
45890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                throw new AssertionError();
45900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
45910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
45920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Remember the current tab.
45930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            TabControl.Tab current = mTabControl.getCurrentTab();
45940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab remove = mTabControl.getTab(position);
45950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.removeTab(remove);
45960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // If we removed the current tab, use the tab at position - 1 if
45970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // possible.
45980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (current == remove) {
45990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // If the user removes the last tab, act like the New Tab item
46000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // was clicked on.
46010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (mTabControl.getTabCount() == 0) {
4602f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                    current = mTabControl.createNewTab();
4603ec7eb37292836652e096b5804877e803e2505136Grace Kloba                    sendAnimateFromOverview(current, true, new UrlData(
4604ec7eb37292836652e096b5804877e803e2505136Grace Kloba                            mSettings.getHomePage()), TAB_OVERVIEW_DELAY, null);
46050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                } else {
46060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    final int index = position > 0 ? (position - 1) : 0;
46070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    current = mTabControl.getTab(index);
46080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
46090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // The tab overview could have been dismissed before this method is
46120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // called.
46130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mTabOverview != null) {
46140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // Remove the tab and change the index.
46150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabOverview.remove(position);
46160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabOverview.setCurrentIndex(mTabControl.getTabIndex(current));
46170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Only the current tab ensures its WebView is non-null. This
46200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // implies that we are reloading the freed tab.
46210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.setCurrentTab(current);
46220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        public void onClick(int index) {
46240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Change the tab if necessary.
46250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // Index equals ImageGrid.CANCEL when pressing back from the tab
46260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // overview.
46270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (index == ImageGrid.CANCEL) {
46280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                index = mTabControl.getCurrentIndex();
46290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                // The current index is -1 if the current tab was removed.
46300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                if (index == -1) {
46310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // Take the last tab as a fallback.
46320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    index = mTabControl.getTabCount() - 1;
46330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
46340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // NEW_TAB means that the "New Tab" cell was clicked on.
46370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (index == ImageGrid.NEW_TAB) {
4638f59ec877363eaf43118677f249008eddc7a9ce11The Android Open Source Project                openTabAndShow(mSettings.getHomePage(), null, false, null);
46390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            } else {
4640ec7eb37292836652e096b5804877e803e2505136Grace Kloba                sendAnimateFromOverview(mTabControl.getTab(index), false,
4641ec7eb37292836652e096b5804877e803e2505136Grace Kloba                        EMPTY_URL_DATA, 0, null);
46420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
46450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // A fake View that draws the WebView's picture with a fast zoom filter.
46470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The View is used in case the tab is freed during the animation because
46480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // of low memory.
46490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static class AnimatingView extends View {
46500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private static final int ZOOM_BITS = Paint.FILTER_BITMAP_FLAG |
46510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                Paint.DITHER_FLAG | Paint.SUBPIXEL_TEXT_FLAG;
46520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private static final DrawFilter sZoomFilter =
46530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                new PaintFlagsDrawFilter(ZOOM_BITS, Paint.LINEAR_TEXT_FLAG);
46540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final Picture mPicture;
46550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final float   mScale;
46560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final int     mScrollX;
46570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        private final int     mScrollY;
46580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab  mTab;
46590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        AnimatingView(Context ctxt, TabControl.Tab t) {
46610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            super(ctxt);
46620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTab = t;
4663ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott            if (t != null && t.getTopWindow() != null) {
4664ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                // Use the top window in the animation since the tab overview
4665ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                // will display the top window in each cell.
4666ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                final WebView w = t.getTopWindow();
4667ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mPicture = w.capturePicture();
4668ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScale = w.getScale() / w.getWidth();
4669ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScrollX = w.getScrollX();
4670ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScrollY = w.getScrollY();
4671ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott            } else {
4672ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mPicture = null;
4673ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScale = 1.0f;
4674ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott                mScrollX = mScrollY = 0;
4675ae641ac4bbe1c7c3fb235774cb84d910573595c7Patrick Scott            }
46760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        @Override
46790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        protected void onDraw(Canvas canvas) {
46800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            canvas.save();
46810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            canvas.drawColor(Color.WHITE);
46820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (mPicture != null) {
46830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.setDrawFilter(sZoomFilter);
46840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                float scale = getWidth() * mScale;
46850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.scale(scale, scale);
46860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.translate(-mScrollX, -mScrollY);
46870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                canvas.drawPicture(mPicture);
46880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
46890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            canvas.restore();
46900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
46910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
46920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
46930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
46940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  Open the tab picker. This function will always use the current tab in
46950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  its animation.
46960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  @param stay boolean stating whether the tab picker is to remain open
46970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *          (in which case it needs a listener and its menu) or not.
46980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  @param index The index of the tab to show as the selection in the tab
46990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *               overview.
47000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *  @param remove If true, the tab at index will be removed after the
47010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *                animation completes.
47020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
47030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void tabPicker(final boolean stay, final int index,
47040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final boolean remove) {
47050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mTabOverview != null) {
47060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
47070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int size = mTabControl.getTabCount();
47100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        TabListener l = null;
47120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (stay) {
47130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            l = mTabListener = new TabListener();
47140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview = new ImageGrid(this, stay, l);
47160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        for (int i = 0; i < size; i++) {
47180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            final TabControl.Tab t = mTabControl.getTab(i);
47190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.populatePickerData(t);
47200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabOverview.add(t);
47210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Tell the tab overview to show the current tab, the tab overview will
47240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // handle the "New Tab" case.
47250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        int currentIndex = mTabControl.getCurrentIndex();
47260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mTabOverview.setCurrentIndex(currentIndex);
47270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Attach the tab overview.
47290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(mTabOverview, COVER_SCREEN_PARAMS);
47300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Create a fake AnimatingView to animate the WebView's picture.
47320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final TabControl.Tab current = mTabControl.getCurrentTab();
47330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        final AnimatingView v = new AnimatingView(this, current);
47340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mContentView.addView(v, COVER_SCREEN_PARAMS);
47350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        removeTabFromContentView(current);
47360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Pause timers to get the animation smoother.
47370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        current.getWebView().pauseTimers();
47380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Send a message so the tab picker has a chance to layout and get
47400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // positions for all the cells.
47410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mHandler.sendMessage(mHandler.obtainMessage(ANIMATE_TO_OVERVIEW,
47420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                index, remove ? 1 : 0, v));
47430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Setting this will indicate that we are animating to the overview. We
47440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // set it here to prevent another request to animate from coming in
47450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // between now and when ANIMATE_TO_OVERVIEW is handled.
47460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mAnimationCount++;
47470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Always change the title bar to the window overview title while
47480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // animating.
474981db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        if (CUSTOM_BROWSER_BAR) {
475081db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            mTitleBar.setToTabPicker();
475181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        } else {
475281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, null);
475381db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, null);
475481db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
475581db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins                    Window.PROGRESS_VISIBILITY_OFF);
475681db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins            setTitle(R.string.tab_picker_title);
475781db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins        }
47580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Make the menu empty until the animation completes.
47590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        mMenuState = EMPTY_MENU;
47600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
47610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4762e4b3bda762ab616b2899c8de084e515f01b99c8aLeon Scroggins    /* package */ void bookmarksOrHistoryPicker(boolean startWithHistory) {
47630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        WebView current = mTabControl.getCurrentWebView();
47640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (current == null) {
47650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return;
47660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Intent intent = new Intent(this,
47680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                CombinedBookmarkHistoryActivity.class);
47690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String title = current.getTitle();
47700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String url = current.getUrl();
47710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // Just in case the user opens bookmarks before a page finishes loading
47720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // so the current history item, and therefore the page, is null.
47730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (null == url) {
47740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = mLastEnteredUrl;
47750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // This can happen.
47760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (null == url) {
47770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                url = mSettings.getHomePage();
47780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
47790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the web page has not yet received its associated title.
47810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (title == null) {
47820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            title = url;
47830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("title", title);
47850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("url", url);
47860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        intent.putExtra("maxTabsOpen",
47870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                mTabControl.getTabCount() >= TabControl.MAX_TABS);
47880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (startWithHistory) {
47890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
47900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
47910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
47920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        startActivityForResult(intent, COMBO_PAGE);
47930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
47940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
47950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Called when loading from context menu or LOAD_URL message
47960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void loadURL(WebView view, String url) {
47970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // In case the user enters nothing.
47980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url != null && url.length() != 0 && view != null) {
47990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            url = smartUrlFilter(url);
48000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!mWebViewClient.shouldOverrideUrlLoading(view, url)) {
48010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                view.loadUrl(url);
48020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
48030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
48040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
48050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private void checkMemory() {
48070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
48080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        ((ActivityManager) getSystemService(ACTIVITY_SERVICE))
48090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                .getMemoryInfo(mi);
48100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // FIXME: mi.lowMemory is too aggressive, use (mi.availMem <
48110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        // mi.threshold) for now
48120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        //        if (mi.lowMemory) {
48130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (mi.availMem < mi.threshold) {
48140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Log.w(LOGTAG, "Browser is freeing memory now because: available="
48150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (mi.availMem / 1024) + "K threshold="
48160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                            + (mi.threshold / 1024) + "K");
48170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            mTabControl.freeMemory();
48180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
48190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
48200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String smartUrlFilter(Uri inUri) {
48220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (inUri != null) {
48230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return smartUrlFilter(inUri.toString());
48240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
48250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return null;
48260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
48270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get window count
48300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    int getWindowCount(){
48320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      if(mTabControl != null){
48330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return mTabControl.getTabCount();
48340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      }
48350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      return 0;
48360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
48370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
4838b34f87a2e13af13d697130482af01b537ab7c5fdFeng Qian    protected static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
48390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?i)" + // switch on case insensitive matching
48400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(" +    // begin group for schema
48410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(?:http|https|file):\\/\\/" +
484225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            "|(?:inline|data|about|content|javascript):" +
48430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            ")" +
48440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            "(.*)" );
48450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /**
48470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Attempts to determine whether user input is a URL or search
48480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * terms.  Anything with a space is passed to search.
48490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
48500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * Converts to lowercase any mistakenly uppercased schema (i.e.,
48510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * "Http://" converts to "http://"
48520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
48530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     * @return Original or modified URL
48540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     *
48550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project     */
48560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    String smartUrlFilter(String url) {
48570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        String inUrl = url.trim();
48590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        boolean hasSpace = inUrl.indexOf(' ') != -1;
48600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
48620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (matcher.matches()) {
48630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            // force scheme to lowercase
48640c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String scheme = matcher.group(1);
48650c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            String lcScheme = scheme.toLowerCase();
48660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (!lcScheme.equals(scheme)) {
4867123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = lcScheme + matcher.group(2);
4868123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            }
4869123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima            if (hasSpace) {
4870123ecfb21e7ca670e3d04efe58780b3bac54a9a1Mitsuru Oshima                inUrl = inUrl.replace(" ", "%20");
48710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
48720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            return inUrl;
48730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
48740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (hasSpace) {
4875565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // FIXME: Is this the correct place to add to searches?
4876565505b1a2c1d3099496af5910760087602e994aSatish Sampath            // what if someone else calls this function?
4877565505b1a2c1d3099496af5910760087602e994aSatish Sampath            int shortcut = parseUrlShortcut(inUrl);
4878565505b1a2c1d3099496af5910760087602e994aSatish Sampath            if (shortcut != SHORTCUT_INVALID) {
4879565505b1a2c1d3099496af5910760087602e994aSatish Sampath                Browser.addSearchUrl(mResolver, inUrl);
4880565505b1a2c1d3099496af5910760087602e994aSatish Sampath                String query = inUrl.substring(2);
4881565505b1a2c1d3099496af5910760087602e994aSatish Sampath                switch (shortcut) {
4882565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_SEARCH:
4883565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return composeSearchUrl(query);
4884565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_WIKIPEDIA_SEARCH:
4885565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
4886565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_DICTIONARY_SEARCH:
4887565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
4888565505b1a2c1d3099496af5910760087602e994aSatish Sampath                case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
48890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    // FIXME: we need location in this case
4890565505b1a2c1d3099496af5910760087602e994aSatish Sampath                    return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
48910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                }
48920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
48930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
48940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            if (Regex.WEB_URL_PATTERN.matcher(inUrl).matches()) {
48950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                return URLUtil.guessUrl(inUrl);
48960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            }
48970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
48980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
48990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        Browser.addSearchUrl(mResolver, inUrl);
49000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return composeSearchUrl(inUrl);
49010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
49020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */ String composeSearchUrl(String search) {
49040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        return URLUtil.composeSearchUrl(search, QuickSearch_G,
49050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                QUERY_PLACE_HOLDER);
49060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
49070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* package */void setBaseSearchUrl(String url) {
49090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        if (url == null || url.length() == 0) {
49100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            /*
49110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * get the google search url based on the SIM. Default is US. NOTE:
49120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * This code uses resources to optionally select the search Uri,
49130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * based on the MCC value from the SIM. The default string will most
49140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * likely be fine. It is parameterized to accept info from the
49150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * Locale, the language code is the first parameter (%1$s) and the
49160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * country code is the second (%2$s). This code must function in the
49170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * same way as a similar lookup in
49180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * com.android.googlesearch.SuggestionProvider#onCreate(). If you
49190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * change either of these functions, change them both. (The same is
49200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * true for the underlying resource strings, which are stored in
49210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             * mcc-specific xml files.)
49220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project             */
49230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Locale l = Locale.getDefault();
4924e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            String language = l.getLanguage();
4925e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            String country = l.getCountry().toLowerCase();
4926e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            // Chinese and Portuguese have two langauge variants.
4927e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            if ("zh".equals(language)) {
4928e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                if ("cn".equals(country)) {
4929e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language = "zh-CN";
4930e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                } else if ("tw".equals(country)) {
4931e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language = "zh-TW";
4932e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                }
4933e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            } else if ("pt".equals(language)) {
4934e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                if ("br".equals(country)) {
4935e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language = "pt-BR";
4936e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                } else if ("pt".equals(country)) {
4937e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language = "pt-PT";
4938e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                }
4939e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier            }
49400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            QuickSearch_G = getResources().getString(
4941e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    R.string.google_search_base,
4942e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    language,
4943e9651c3366520fcbc1fba6b3ee662cae95fcea7bBill Napier                    country)
49440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + "client=ms-"
4945dd4f4297c08803b238af28dddb373a1aea06cc1eRamanan Rajeswaran                    + Partner.getString(this.getContentResolver(), Partner.CLIENT_ID)
49460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                    + "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&q=%s";
49470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        } else {
49480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            QuickSearch_G = url;
49490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project        }
49500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    }
49510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int LOCK_ICON_UNSECURE = 0;
49530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int LOCK_ICON_SECURE   = 1;
49540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int LOCK_ICON_MIXED    = 2;
49550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mLockIconType = LOCK_ICON_UNSECURE;
49570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mPrevLockType = LOCK_ICON_UNSECURE;
49580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BrowserSettings mSettings;
49600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl      mTabControl;
49610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ContentResolver mResolver;
49620c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FrameLayout     mContentView;
49630c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ImageGrid       mTabOverview;
4964adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private View            mCustomView;
4965adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private FrameLayout     mCustomViewContainer;
49660c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
49680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // view, we should rewrite this.
49690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mCurrentMenuState = 0;
49700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mMenuState = R.id.MAIN_MENU;
4971adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    private int mOldMenuState = EMPTY_MENU;
49720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int EMPTY_MENU = -1;
49730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Menu mMenu;
49740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private FindDialog mFindDialog;
49760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used to prevent chording to result in firing two shortcuts immediately
49770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // one after another.  Fixes bug 1211714.
49780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    boolean mCanChord;
49790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mInLoad;
49810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mIsNetworkUp;
49820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mPageStarted;
49840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mActivityInPause = true;
49850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mMenuIsDown;
49870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final KeyTracker mKeyTracker = new KeyTracker(this);
49890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As trackball doesn't send repeat down, we have to track it ourselves
49910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private boolean mTrackTrackball;
49920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static boolean mInTrace;
49940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
49950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Performance probe
49960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
49970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
49980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
49990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
50000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
50010c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
50020c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
50030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
50040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
50050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    };
50060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mStart;
50080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mProcessStart;
50090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUserStart;
50100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mSystemStart;
50110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIdleStart;
50120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mIrqStart;
50130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private long mUiStart;
50150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mMixLockIcon;
50170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mSecLockIcon;
50180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Drawable    mGenericFavicon;
50190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50200c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /* hold a ref so we can auto-cancel if necessary */
50210c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mAlertDialog;
50220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50230c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wait for credentials before loading google.com
50240c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private ProgressDialog mCredsDlg;
50250c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50260c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // The up-to-date URL and title (these can be different from those stored
50270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // in WebView, since it takes some time for the information in WebView to
50280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // get updated)
50290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mUrl;
50300c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mTitle;
50310c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50320c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As PageInfo has different style for landscape / portrait, we have
50330c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // to re-open it when configuration changed
50340c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mPageInfoDialog;
50350c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mPageInfoView;
50360c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // If the Page-Info dialog is launched from the SSL-certificate-on-error
50370c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // dialog, we should not just dismiss it, but should get back to the
50380c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // SSL-certificate-on-error dialog. This flag is used to store this state
50390c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Boolean mPageInfoFromShowSSLCertificateOnError;
50400c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50410c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificateOnError has different style for landscape / portrait,
50420c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // we have to re-open it when configuration changed
50430c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateOnErrorDialog;
50440c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private WebView mSSLCertificateOnErrorView;
50450c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslErrorHandler mSSLCertificateOnErrorHandler;
50460c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private SslError mSSLCertificateOnErrorError;
50470c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50480c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as SSLCertificate has different style for landscape / portrait, we
50490c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
50500c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mSSLCertificateDialog;
50510c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabControl.Tab mSSLCertificateView;
50520c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50530c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // as HttpAuthentication has different style for landscape / portrait, we
50540c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // have to re-open it when configuration changed
50550c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private AlertDialog mHttpAuthenticationDialog;
50560c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private HttpAuthHandler mHttpAuthHandler;
50570c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50580c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
50590c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            new FrameLayout.LayoutParams(
50600c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT,
50610c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project                                            ViewGroup.LayoutParams.FILL_PARENT);
5062adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
5063adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            new FrameLayout.LayoutParams(
5064adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            ViewGroup.LayoutParams.FILL_PARENT,
5065adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            ViewGroup.LayoutParams.FILL_PARENT,
5066adc008d2d87676a2a32e93afba20156a2bf2355bAndrei Popescu                                            Gravity.CENTER);
50670c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // We may provide UI to customize these
50680c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google search from the browser
50690c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    static String QuickSearch_G;
50700c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Wikipedia search
50710c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
50720c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Dictionary search
50730c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
50740c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Google Mobile Local search
50750c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
50760c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50770c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String QUERY_PLACE_HOLDER = "%s";
50780c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50790c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through search key
50800c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
50810c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through goto menu
50820c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
50830c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search through simplily type
50840c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
50850c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search suggested by the browser
50860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
50870c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // "source" parameter for Google search from unknown source
50880c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
50890c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50900c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static String LOGTAG = "browser";
50910c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50920c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private TabListener mTabListener;
50930c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50940c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private String mLastEnteredUrl;
50950c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50960c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private PowerManager.WakeLock mWakeLock;
50970c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
50980c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
50990c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private Toast mStopToast;
51000c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
510181db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins    private TitleBar mTitleBar;
510281db366d79bb317de62fed05eb58906abd88a75eLeon Scroggins
51030c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // Used during animations to prevent other animations from being triggered.
51040c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // A count is used since the animation to and from the Window overview can
51050c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // overlap. A count of 0 means no animation where a count of > 0 means
51060c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // there are animations in progress.
51070c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private int mAnimationCount;
51080c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
51090c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // As the ids are dynamically created, we can't guarantee that they will
51100c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // be in sequence, so this static array maps ids to a window number.
51110c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
51120c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
51130c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
51140c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
51150c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
51160c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // monitor platform changes
51170c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private IntentFilter mNetworkStateChangedFilter;
51180c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    private BroadcastReceiver mNetworkStateIntentReceiver;
51190c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
5120b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba    private BroadcastReceiver mPackageInstallationReceiver;
5121b4da0ad0351996f639b50f9f29b123a9b5c24fd0Grace Kloba
51220c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // activity requestCode
512378a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int COMBO_PAGE                 = 1;
512478a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int DOWNLOAD_PAGE              = 2;
512578a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int PREFERENCES_PAGE           = 3;
512678a98e459323f938e97789a6131beddbebb459ceNicolas Roard    final static int WEBSTORAGE_QUOTA_DIALOG    = 4;
51270c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project
51280c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    // the frenquency of checking whether system memory is low
51290c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project    final static int CHECK_MEMORY_INTERVAL = 30000;     // 30 seconds
513025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
513125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
513225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A UrlData class to abstract how the content will be set to WebView.
513325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * This base class uses loadUrl to show the content.
513425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
513525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class UrlData {
513625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mUrl;
513760e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        byte[] mPostData;
513860e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
513925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        UrlData(String url) {
514025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            this.mUrl = url;
514125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
514260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
514360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        void setPostData(byte[] postData) {
514460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            mPostData = postData;
514560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba        }
514660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba
514725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
514825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            return mUrl == null || mUrl.length() == 0;
514925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
515025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
51517944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        public void loadIn(WebView webView) {
515260e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            if (mPostData != null) {
515360e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                webView.postUrl(mUrl, mPostData);
515460e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            } else {
515560e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba                webView.loadUrl(mUrl);
515660e095c190496d42327f8ec2ef990c044d15a76fGrace Kloba            }
515725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
515825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    };
515925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
516025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    /**
516125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * A subclass of UrlData class that can display inlined content using
516225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     * {@link WebView#loadDataWithBaseURL(String, String, String, String, String)}.
516325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima     */
516425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static class InlinedUrlData extends UrlData {
516525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        InlinedUrlData(String inlined, String mimeType, String encoding, String failUrl) {
516625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            super(failUrl);
516725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mInlined = inlined;
516825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mMimeType = mimeType;
516925ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            mEncoding = encoding;
517025ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
517125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mMimeType;
517225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mInlined;
517325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        String mEncoding;
51747944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        @Override
517525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        boolean isEmpty() {
517625ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            return mInlined == null || mInlined.length() == 0 || super.isEmpty();
517725ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
517825ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
51797944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        @Override
51807944b7def8b04c3dc0cb8815a8527aba8c91b219Mitsuru Oshima        public void loadIn(WebView webView) {
518125ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima            webView.loadDataWithBaseURL(null, mInlined, mMimeType, mEncoding, mUrl);
518225ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima        }
518325ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    }
518425ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima
518525ad8ab821d67293a5f53e8d341492be06e187eeMitsuru Oshima    private static final UrlData EMPTY_URL_DATA = new UrlData(null);
51860c90888c75eed12f6e2e14a9044faf50bd4af8edThe Android Open Source Project}
5187