Porting 1847 and 1599-qrd browser changes

---

  Fix issue with exit dialog showing on downloads

   The dialog was only shown when the download was initiated from
   outside the browser.  Added a property to Tab to identify
   it was created from an intent and handle closing it appropriately.

   Change-Id: I83d342571f3fbf74223e248dd6bb6a8660bca96b

---

  Memory monitor not deleting tabs when switching tabs.
   Fixed bug where tab.destroy() was called only when new tab is
   created. Fix was to check for stale tab when setActiveTab is
   called and destroy webview for it.
   Change-Id: Ibcb6431039ac97fcf21aaab4ace0dfb27f4227dc

---

  Fix content disposition having multiple attributes
   Change-Id: If04e930f16243dd1d4ee0acec3a31dfff971ea78

---

  Fix yahoo search url where url 'http://cn.search.yahoo.com' is
  redirected to 'http://sg.search.yahoo.com/' and query string is
  lost in redirection.
   Change-Id: I326d15528ae3b7a1cd7d90ca7a454c3bfbddfdd2

---

  Fix issue in Autofill delete button
   Change-Id: I9dff2a21d976c3269455b2d112cc964980642f82

---

  Smoother tab transition and miscellaneous UI fixes.
   - Fixed white screen issue seen when render process
     was killed during tab switches.
   - Fixed jankiness with animation during tab switching.
   - Fixed issue where cancelling a dialog was causing
     the menu item to be disabled.
   Change-Id: I099b7ed3fdd8e10142f5ce932192f9db19f9650f

---

  Fixes crash view to be shown for background tabs
   Change-Id: I128e165ecfa7fa44c1d98ba13c5b22719c12d2a7

---

   Fix timing issue with tab animation

    A max num counter is introduced to put a upper limit on time to wait
    for the tab (SurfaceView) to be ready.  This fixes issue seens on JB

    Change-Id: I5519534bc2ea572ca7eb4bb3b1f27921315e9359

---

   Allow copy URI for My Navigation page

    Change-Id: Ic98a2ad426462df7adf748b15b7e2e70a00d382e

---

   Enable WLAN checks.

   - Enable WLAN access point selection if WLAN is enabled
     and access point is available.
   - Prompt user to enable mobile data when WLAN is enabled
     access point is not available.

   Change-Id: I97e0a0053b07357ee438c0d48d0adfa8abbd80a2

---

   Introspect mimetype for octect stream mimetype based on file extension.

     Change-Id: I2b3e039647cf60b595d36261cf2ee391207304bc

---

   Fix crash when handler is null

     Change-Id: I09afd1e8558a5e6473df5b44b5cf4e2584feefe9

---

  Fix for JS interface required for overlay default home page

    Modified how the JS interface is initialized for the default
    home page and included it during the restore of default page.

   Change-Id: I077dc8d56aeb6a1db6159dd8f2a1b812b4cd2c79
---

    Multiple fixes to SWE.

    - Fix showing added navigation correctly.
    - Fix showing white screen when creating new tab.

    Change-Id: I209f7f5a903a930f021f0a680547bba3dd74d597

---
     Pause newly created tab when it is in background

     - When a new tab is opened in background, we need to ensure that the
       tab is properly paused.

     Change-Id: I45e1286de2a89d74581decf3c0c2a23655ae0c47
---
     Fix for disappearing title bar caused by copy/paste control

     Change-Id: I19860bd9356b2dc392539aa1e16819545e32de6d

---
     Geolocation improvements

      - Provide users the option to make geolocation permission choices that are
        only good for a day.
      - Add a clickable icon to indicate that a site has permission to request
        Geolocation information. Selecting the icon allows the user to edit/clear
        the geolocation policy for the current origin
      - Enhanced preferences under Settings > Advanced > Website settings to allow
        users to modify/clear the per origin geolocation policy
      - Disable importing approved origins from
        /data/data/com.android.providers.settings/databases/settings.db

      Change-Id: Iafe0ea63f487e06bffecea4fbfc6db2b7b0b85c6

---
      Add DuckDuckGo to list of search engines

       - User can now switch to DuckDuckGo from Settings->Advanced->Set search engine.

      Change-Id: I2ef5624d1eea7bd257c6619cc65b057ed865b5df
---
      Capture thumbnail when tab is paused

        - Fixes blank tab thumbnail when a tab is opened via adb comman

      Change-Id: I817d65575c88c37e6ac5828ea8e561dae6a14ba6
---
      Fix for tab thumbnail preview cropped in landscape orientation

      Change-Id: Id7c14ddad2e465a9057d6cc85710b1f0dc660739
---
      Change menu id for automation test

      Change-Id: Ic089b303d39f8677debeae292b8fd2bad096baef
---
     Do Not Track (Browser)

       - Browser modifications to set the Do Not Track privacy option.

       Change-Id: I262b7a05d43b39837cb84eb79f5844d14277e3fd
---

Change-Id: Icc95bdf4bd8d2bd3e3282f77d7f6a88232b59cda
diff --git a/src/com/android/browser/LocationButton.java b/src/com/android/browser/LocationButton.java
new file mode 100644
index 0000000..e805e43
--- /dev/null
+++ b/src/com/android/browser/LocationButton.java
@@ -0,0 +1,257 @@
+/*
+ *  Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *      * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.browser;
+
+import org.codeaurora.swe.GeolocationPermissions;
+import org.codeaurora.swe.GeolocationPermissions.OnGeolocationPolicyModifiedListener;
+import org.json.JSONArray;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.net.Uri;
+import android.util.AttributeSet;
+import android.view.View;
+import android.webkit.ValueCallback;
+import android.widget.ImageButton;
+
+public class LocationButton extends ImageButton
+        implements OnGeolocationPolicyModifiedListener {
+    private GeolocationPermissions mGeolocationPermissions;
+    private long mCurrentTabId;
+    private String mCurrentOrigin;
+    private boolean mCurrentIncognito;
+
+    private static final long MILLIS_PER_DAY = 86400000;
+
+    protected long geolocationPolicyExpiration;
+    protected boolean geolocationPolicyOriginAllowed;
+
+    public LocationButton(Context context) {
+        super(context);
+    }
+
+    public LocationButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+    }
+
+    public LocationButton(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        init();
+    }
+
+    private void init() {
+        mGeolocationPermissions = GeolocationPermissions.getInstance();
+        mGeolocationPermissions.registerOnGeolocationPolicyModifiedListener(this);
+        mCurrentTabId = -1;
+        mCurrentOrigin = null;
+        mCurrentIncognito = false;
+
+        setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (!mCurrentOrigin.isEmpty()) {
+                    final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+                    final GeolocationPermissions geolocationPermissions =
+                            (mCurrentIncognito ?
+                                    GeolocationPermissions.getIncognitoInstance() :
+                                    GeolocationPermissions.getInstance());
+
+                    DialogInterface.OnClickListener alertDialogListener =
+                            new AlertDialog.OnClickListener() {
+                        public void onClick(DialogInterface dlg, int which) {
+                            String origin = mCurrentOrigin;
+                            int selectedPosition = ((AlertDialog)dlg)
+                                    .getListView().getCheckedItemPosition();
+                            switch (selectedPosition) {
+                                case 0: // Deny forever
+                                    geolocationPermissions.deny(origin);
+                                    break;
+                                case 1: // Extend for 24 hours
+                                    // encode the expiration time and origin as a JSON string
+                                    JSONArray jsonArray = new JSONArray();
+                                    jsonArray.put(System.currentTimeMillis() + MILLIS_PER_DAY);
+                                    jsonArray.put(origin);
+                                    geolocationPermissions.allow(jsonArray.toString());
+                                    break;
+                                case 2: // Allow forever
+                                    geolocationPermissions.allow(origin);
+                                    break;
+                                case 3: // Always ask
+                                    geolocationPermissions.clear(origin);
+                                    break;
+                                default:
+                                    break;
+                            }
+                        }};
+
+                    builder.setTitle(String.format(getResources()
+                            .getString(R.string.geolocation_settings_page_dialog_title),
+                                "http".equals(Uri.parse(mCurrentOrigin).getScheme()) ?
+                                        mCurrentOrigin.substring(7) : mCurrentOrigin))
+                        .setPositiveButton(R.string.geolocation_settings_page_dialog_ok_button,
+                                           alertDialogListener)
+                        .setNegativeButton(R.string.geolocation_settings_page_dialog_cancel_button, null);
+
+                    final ValueCallback<Long> getExpirationCallback = new ValueCallback<Long>() {
+                        public void onReceiveValue(Long expirationTime) {
+                            if (expirationTime != null) {
+                                geolocationPolicyExpiration = expirationTime.longValue();
+                                // Set radio button and location icon
+                                if (!geolocationPolicyOriginAllowed) {
+                                    // 0: Deny forever
+                                    builder.setSingleChoiceItems(R.array.geolocation_settings_choices, 0, null);
+                                } else {
+                                    if (geolocationPolicyExpiration
+                                            != GeolocationPermissions.DO_NOT_EXPIRE) {
+                                        // 1: Allow for 24 hours
+                                        builder.setSingleChoiceItems(R.array.geolocation_settings_choices, 1, null);
+                                    } else {
+                                        // 2: Allow forever
+                                        builder.setSingleChoiceItems(R.array.geolocation_settings_choices, 2, null);
+                                    }
+                                }
+                            }
+                            builder.show();
+                        }};
+
+                    final ValueCallback<Boolean> getAllowedCallback = new ValueCallback<Boolean>() {
+                        public void onReceiveValue(Boolean allowed) {
+                            if (allowed != null) {
+                                geolocationPolicyOriginAllowed = allowed.booleanValue();
+                                //Get the policy expiration time
+                                geolocationPermissions
+                                    .getExpirationTime(mCurrentOrigin, getExpirationCallback);
+                            }
+                        }};
+
+                    geolocationPermissions.hasOrigin(mCurrentOrigin,
+                        new ValueCallback<Boolean>() {
+                            public void onReceiveValue(Boolean hasOrigin) {
+                                if (hasOrigin != null && hasOrigin.booleanValue()) {
+                                    //Get whether origin is allowed or denied
+                                    geolocationPermissions.getAllowed(mCurrentOrigin,
+                                            getAllowedCallback);
+                                }
+                            }
+                        });
+                    }
+                }
+            });
+    }
+
+    public void onTabDataChanged(Tab tab) {
+        long tabId = tab.getId();
+        String origin = GeolocationPermissions.getOriginFromUrl(tab.getUrl());
+        boolean incognito = tab.isPrivateBrowsingEnabled();
+
+        if (mCurrentTabId != tabId) {
+            mCurrentTabId = tabId;
+            mCurrentOrigin = origin;
+
+            // Switch GeolocationPermissions if we went from a regular to an
+            // incognito tab or vice versa
+            if (mCurrentIncognito != incognito) {
+                mCurrentIncognito = incognito;
+                mGeolocationPermissions = mCurrentIncognito ?
+                        GeolocationPermissions.getIncognitoInstance() :
+                            GeolocationPermissions.getInstance();
+                mGeolocationPermissions.registerOnGeolocationPolicyModifiedListener(this);
+            }
+            update();
+        }
+        // Update icon if we are in the same tab and origin has changed
+          else if (!((mCurrentOrigin == null && origin == null) ||
+                (mCurrentOrigin != null && origin != null
+                    && mCurrentOrigin.equals(origin)))) {
+            mCurrentOrigin = origin;
+            update();
+        }
+    }
+
+    public void update() {
+        if (mCurrentOrigin != null) {
+            mGeolocationPermissions.hasOrigin(mCurrentOrigin,
+                    new ValueCallback<Boolean>() {
+                public void onReceiveValue(Boolean hasOrigin) {
+                    if (hasOrigin != null && hasOrigin.booleanValue()) {
+                        mGeolocationPermissions.getAllowed(mCurrentOrigin,
+                                new ValueCallback<Boolean>() {
+                            public void onReceiveValue(Boolean allowed) {
+                                if (allowed != null) {
+                                    if (allowed.booleanValue()) {
+                                        LocationButton.this.setImageResource(R.drawable.ic_gps_on_holo_dark);
+                                        LocationButton.this.setVisibility(VISIBLE);
+                                    } else {
+                                        LocationButton.this.setImageResource(R.drawable.ic_gps_denied_holo_dark);
+                                        LocationButton.this.setVisibility(VISIBLE);
+                                    }
+                                }
+                            }
+                        });
+                    } else {
+                        LocationButton.this.setVisibility(GONE);
+                    }
+                }
+            });
+        } else {
+            this.setVisibility(GONE);
+        }
+    }
+
+    @Override
+    public void onGeolocationPolicyAdded(String origin, boolean allow) {
+        if (mCurrentOrigin != null && mCurrentOrigin.equals(origin)) {
+            this.setImageResource(allow ? R.drawable.ic_gps_on_holo_dark :
+                R.drawable.ic_gps_denied_holo_dark);
+            this.setVisibility(VISIBLE);
+        }
+    }
+
+    @Override
+    public void onGeolocationPolicyCleared(String origin) {
+        if (mCurrentOrigin != null && mCurrentOrigin.equals(origin)) {
+            this.setVisibility(GONE);
+        }
+    }
+
+    @Override
+    public void onGeolocationPolicyClearedAll() {
+        this.setVisibility(GONE);
+    }
+
+}