Porting browser changes from 1599-qrd to 1847

-----
    Added WebsiteSettingsFragment in known fragments

    Missing fragment was causing 'Settings > Advanced > Website settings'
    to crash.

    Change-Id: Iaf99a292293e269a1f359acb52f3448ed90c2abc

-----
   Increase max sandboxed process services to 19
   in SWE Browser manifest matching the content shell.

-----
   Hide title bar feature is enabled and required callbacks are
   implemented.

  - Add a new setting to allow media downloads

    - if audio and video mimetype based urls which do not
      have "Content-Dispostion: attachment" in response header
      should be allowed to download or not

      Change-Id: If5892db0bbfb81eaa6b0ae2a7e1ae81e98d08d33

  - Add "modify audio settings" permission in AndroidManifest for browser

     Change-Id: I68bf299785839cf2b11b78d1d53f6ec03bd10b62

  - Browser to allow adding extra HTTP headers.

     Change-Id: Ibd6b76a0001fd6e08cc0565231b09efe0f63bdf2

  - Allow auto play without Gesture

     Change-Id: I666658ae6955a43ab346d01e733ef6480e615ce1

  - Expose 'def_enable_media_downloads' for clients to override Media download option.

     Change-Id: I026d7982fa2507d5f461bdae04d2f6413f2eb822

  - Hide LIVE_MENU items on non http/https pages

    - Hide the following menu items on non http/https URIs
       - Share page
       - Find on page
       - Request desktop site
       - Save for offline reading

     Change-Id: I54de428130a2aab27d1eb4b67b84d2911ae356b2

   - Enable Save for offline option only after page is fully loaded.

      Change-Id: I876756f412f3c9462042bccf8a4a7f970e801185

   - FetchUrlMimeType was not encoding URL before calling HttpHead.

      Change-Id: Ib389963af0f391a5a59bbbd83feeedcf8e3dfb8d

   - Chinese translation for "Allow Media Downloads"

      Change-Id: I5a8822383d79af33e771db4c9e8ead03ebefe333

   - Show only the partial screenshot instead of the
     whole viewport when switching back to tab.

      Change-Id: I442b1256460ac4da1c40941ea7a1934b8675cb3a

    - Fix navigation screen animation issues

       Height of titlebar was incorrectly added twice to the calculation of
       animation parameters causing: (i) AnimScreen view to be drawed below
       the NavTabView when swithing to navigation screen, and (ii) screen
       flashing when selecting a tab from the navigation screen.

       Change-Id: Ifec1a4a8b5832802cad7658e202f0611fb8c3bfb

     - Fix saving state for tabs purged by memory monitor

        Fetching the incognito property from the Tab's webview was causing Tabs
        whose webview was set to null (e.g. by the memory monitor) to be skipped
        when saving state. The fix uses an existing Tab API that does not presume
        that a Tab has a webview attached.

        Change-Id: I15c8c77431548ea5818ee0572f77afe2e66edf90

     - Fix a continously reloading web page

        Page has JavaScript logic to reload on size change. When titlebar is
        hidden, the content margin is readjusted which is not necessary.
        Fixed by removing the margin adjustment.

        Change-Id: Id26f7785c43dc7a46615dfa03f8fecd77c432dca

     - Fixed browser crash that happened while saving links

        The encodeURL function in FetchUrlMimetype was double encoding
        the URL. This was leading to a corrupted URL. HttpHead was
        throwing an exception due to this.
        The encodeURL was done to fix another problem, where URLs
        with ### characters were causing a crash. Replaced encodeURL
        with URI to check if URL is correct.
        Also, disabled "save link" option for incorrect URLs.

        Change-Id: I99d606c2c59251233fa0ffad9c81138c9baa6342

     - Fix various issues with autohide, quickcontrols and fixed titlebar

        A whitebar is seen when quickcontrols is turned on. Configuring
        to use fixed titlebar doesn't work anymore.  Both issues are fixed
        by repairing the corresponding logic in BaseUi and TitleBar classes.

        A new feature to reveal the titlebar on pageload is added.
        Fullscreen logic is modfied to take into consideration of the state
        of quickcontrols and the fullscreen browser setting.  Without these
        changes, going to fullscreen shows unneeded titlebar.

        Change-Id: I2358f3b8aec5bf28a49870fb1a8c4f49aa168351

     - Use regular tab for loading url in "go live" option

        - This use normal tab for loading live pages instead of
          snapshot tab.

        Change-Id: Iebe8278394d983f461892a91813a35f94fd8bde3

     - Fix for saved pages thumbnails

        - Properly scale down screenshot bitmaps prior to saving as thumbnails.
          Addresses the issue of partially displaying saved pages thumbnails as
          well as UI crashes and slow scrolling when there is a large number of
          saved pages.

        Change-Id: Ib89722da767759740773f0ce3a6f018b5782a8a5

      - Prune bitmap recycle calls

         Remove recycle() calls in preference to setting the bitmap to null
         to avoid accidental deletion of a bitmap when its still in use.

         Change-Id: I7c67eecafdcaf0795de3250fe10650bef7dd76d8

      - Fixes back navigation when UserAgent is changed on new tab

          When clicking a link opens up a new tab, and the user agent is
          changed for this new tab, browser was creating a new navigation
          entry. When user clicked back button the browser was going back
          to the same page, instead of removing the tab.

          For example, the user agent can be change by enabling/disabling
          desktop site.

          Change-Id: Id52fb20e9f056ada7d98c665b3274d85a2252935
-----
     Comment out geolocation changes.

Change-Id: I001bf88e5cb716fcce4b066893631627d2aee76d
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b9b67d1..fb5e875 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -53,6 +53,7 @@
     <uses-permission android:name="android.permission.VIBRATE"/>
     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
 
     <application   android:name="Browser"
                    android:label="@string/application_name_swe"
@@ -380,6 +381,36 @@
                  android:permission="org.chromium.content_shell.permission.SANDBOX"
                  android:isolatedProcess="true"
                  android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService14"
+                 android:process=":sandboxed_process14"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService15"
+                 android:process=":sandboxed_process15"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService16"
+                 android:process=":sandboxed_process16"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService17"
+                 android:process=":sandboxed_process17"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService18"
+                 android:process=":sandboxed_process18"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService19"
+                 android:process=":sandboxed_process19"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
     </application>
 
     <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="19" />
diff --git a/res/menu/browser.xml b/res/menu/browser.xml
index 7786034..72f51ff 100644
--- a/res/menu/browser.xml
+++ b/res/menu/browser.xml
@@ -66,11 +66,14 @@
             <item
                 android:id="@+id/find_menu_id"
                 android:title="@string/find_on_page"/>
-            <item
+         <item
                 android:id="@+id/ua_desktop_menu_id"
                 android:checkable="true"
                 android:title="@string/ua_switcher_desktop" />
-            <item
+        </group>
+        <group
+           android:id="@+id/OFFLINE_READING">
+          <item
                 android:id="@+id/save_snapshot_menu_id"
                 android:title="@string/menu_save_snapshot" />
         </group>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 9f4a9f4..0ec0779 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -144,6 +144,7 @@
     <string name="ssl_certificate">"安全证书"</string>
     <string name="ssl_certificate_is_valid">"该证书有效。"</string>
     <string name="pref_memory_monitor">"开启内存监测"</string>
+    <string name="pref_allow_media_downloads">"允许多媒体下载"</string>
     <string name="version">"版本"</string>
     <string name="max_url_character_limit_msg">"达到最大输入长度"</string>
 
diff --git a/res/values/bools.xml b/res/values/bools.xml
index d727c63..1764ea0 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -13,9 +13,12 @@
 <resources
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <bool name="isTablet">false</bool>
-    <!--  hide the title bar -->
-    <bool name="hide_title">false</bool>
-    <bool name="hide_title_on_scroll">false</bool>
+    <!-- hide the title bar
+      When set to false to enable fixed title bar, the command line switch
+      "enable-top-controls-position-calculation" must be turned off by
+      commenting out the relevant code in the Java code
+    -->
+    <bool name="hide_title">true</bool>
     <bool name="hide_nav_buttons">true</bool>
     <!-- Browser menu toggles -->
     <bool name="menu_show_navigation">true</bool>
@@ -25,4 +28,5 @@
     <bool name="drm_uploads">false</bool>
     <bool name="network_notifier">false</bool>
     <bool name="def_disable_history">false</bool>
+    <bool name="def_enable_media_downloads">false</bool>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7558513..78dc9f6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -321,6 +321,8 @@
     <string name="pref_content_javascript">Enable JavaScript</string>
     <!-- Settings label -->
     <string name="pref_memory_monitor">Enable Memory Monitor</string>
+     <!-- Settings label -->
+    <string name="pref_allow_media_downloads">Allow Media Downloads</string>
     <!-- Settings label -->
     <string name="pref_content_open_in_background">Open in background</string>
     <!-- Settings label -->
@@ -807,6 +809,7 @@
     <string name="def_intent_pick_network"></string>
     <string name="def_landing_page"></string>
     <string name="def_useragent"></string>
+    <string name="def_extra_http_headers"></string>
 
     <!-- The default homepage. -->
     <string name="homepage_base" translatable="false">
diff --git a/res/xml-sw600dp/advanced_preferences.xml b/res/xml-sw600dp/advanced_preferences.xml
index 688c70e..c8c9300 100644
--- a/res/xml-sw600dp/advanced_preferences.xml
+++ b/res/xml-sw600dp/advanced_preferences.xml
@@ -41,6 +41,11 @@
             android:defaultValue="true"
             android:title="@string/pref_memory_monitor" />
 
+    <CheckBoxPreference
+            android:key="allow_media_downloads"
+            android:defaultValue="false"
+            android:title="@string/pref_allow_media_downloads" />
+
     <PreferenceScreen
             android:key="website_settings"
             android:title="@string/pref_extras_website_settings"
diff --git a/res/xml/advanced_preferences.xml b/res/xml/advanced_preferences.xml
index 5b2c169..35168a6 100644
--- a/res/xml/advanced_preferences.xml
+++ b/res/xml/advanced_preferences.xml
@@ -42,6 +42,10 @@
             android:title="@string/pref_memory_monitor" />
 
     <CheckBoxPreference
+            android:key="allow_media_downloads"
+            android:title="@string/pref_allow_media_downloads" />
+
+    <CheckBoxPreference
             android:key="allow_apptabs"
             android:defaultValue="false"
             android:title="@string/pref_allow_apptabs" />
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index f05de19..666b997 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -50,7 +50,7 @@
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.Toast;
-
+import android.content.res.TypedArray;
 import com.android.browser.R;
 import com.android.browser.Tab.SecurityState;
 
@@ -819,7 +819,7 @@
         win.setAttributes(winParams);
     }
 
-    public void transalateTitleBar(float topControlsOffsetYPix) {
+    public void translateTitleBar(float topControlsOffsetYPix) {
         if (mTitleBar != null && !mInActionMode) {
             mTitleBar.bringToFront();
             if (topControlsOffsetYPix != 0.0) {
@@ -827,7 +827,9 @@
             } else {
                 mTitleBar.setEnabled(true);
             }
-            mTitleBar.setTranslationY(topControlsOffsetYPix);
+
+            if (!mUseQuickControls)
+                mTitleBar.setTranslationY(topControlsOffsetYPix);
         }
     }
 
@@ -933,27 +935,36 @@
     }
 
     boolean mInActionMode = false;
+    private float getActionModeHeight() {
+        TypedArray actionBarSizeTypedArray = mActivity.obtainStyledAttributes(
+                    new int[] { android.R.attr.actionBarSize });
+        float size = actionBarSizeTypedArray.getDimension(0, 0f);
+        actionBarSizeTypedArray.recycle();
+        return size;
+    }
+
 
     @Override
     public void onActionModeStarted(ActionMode mode) {
         mInActionMode = true;
-        boolean hide_title_on_scroll =
-            mActivity.getResources().getBoolean(R.bool.hide_title_on_scroll);
-        if (!hide_title_on_scroll) {
-            int fixedTbarHeight = mTitleBar.isFixed() ? mTitleBar.calculateEmbeddedHeight() : 0;
+
+        if (mTitleBar.isFixed()) {
+            int fixedTbarHeight = mTitleBar.calculateEmbeddedHeight();
             mFixedTitlebarContainer.setY(fixedTbarHeight);
             setContentViewMarginTop(fixedTbarHeight);
+        } else {
+            mTitleBar.setTranslationY(getActionModeHeight());
         }
     }
 
     @Override
     public void onActionModeFinished(boolean inLoad) {
         mInActionMode = false;
-        boolean hide_title_on_scroll =
-            mActivity.getResources().getBoolean(R.bool.hide_title_on_scroll);
-        if (!hide_title_on_scroll) {
+        if (mTitleBar.isFixed()) {
             mFixedTitlebarContainer.setY(0);
             setContentViewMarginTop(0);
+        } else {
+            mTitleBar.setTranslationY(0);
         }
     }
 }
diff --git a/src/com/android/browser/Browser.java b/src/com/android/browser/Browser.java
index 5a30fad..f042eab 100644
--- a/src/com/android/browser/Browser.java
+++ b/src/com/android/browser/Browser.java
@@ -39,15 +39,9 @@
     // Set to true to enable extra debug logging.
     final static boolean LOGD_ENABLED = true;
 
-    private static final String[] MP_MANDATORY_PAKS = new String[] {
-        "webviewchromium.pak",
-        "icudtl.dat"
-    };
-
     @Override
     public void onCreate() {
         super.onCreate();
-        initializeApplicationParameters();
         if (LOGV_ENABLED)
             Log.v(LOGTAG, "Browser.onCreate: this=" + this);
 
@@ -56,6 +50,8 @@
         final String INITIALIZE_DATABASE = BrowserConfig.AUTHORITY +
                                             ".permission.INITIALIZE_DATABASE";
         final Context context = getApplicationContext();
+        //Chromium specific initialization.
+        Engine.initializeApplicationParameters();
         boolean isActivityContext = (context.checkPermission(INITIALIZE_DATABASE,
               Process.myPid(), Process.myUid()) == PackageManager.PERMISSION_GRANTED);
         if (isActivityContext) {
@@ -66,10 +62,5 @@
        }
 
     }
-
-    public static void initializeApplicationParameters() {
-        ResourceExtractor.setMandatoryPaksToExtract(MP_MANDATORY_PAKS);
-        PathUtils.setPrivateDataDirectorySuffix("android_browser");
-    }
 }
 
diff --git a/src/com/android/browser/BrowserPreferencesPage.java b/src/com/android/browser/BrowserPreferencesPage.java
index fb291c9..09d815e 100644
--- a/src/com/android/browser/BrowserPreferencesPage.java
+++ b/src/com/android/browser/BrowserPreferencesPage.java
@@ -110,7 +110,8 @@
         "com.android.browser.preferences.BandwidthPreferencesFragment",
         "com.android.browser.preferences.LabPreferencesFragment",
         "com.android.browser.preferences.AboutPreferencesFragment",
-        "com.android.browser.AutoFillSettingsFragment"));
+        "com.android.browser.AutoFillSettingsFragment",
+        "com.android.browser.preferences.WebsiteSettingsFragment"));
 
     @Override
     protected boolean isValidFragment(String fragmentName) {
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 2f93d57..c033647 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -281,6 +281,9 @@
         settings.setUseWideViewPort(isWideViewport());
         settings.setDoNotTrack(doNotTrack());
         setUserAgent(settings);
+        settings.setMediaPlaybackRequiresUserGesture(false);
+        settings.setAllowMediaDownloads(allowMediaDownloads());
+        setExtraHTTPRequestHeaders(settings);
 
         WebSettings settingsClassic = (WebSettings) settings;
         settingsClassic.setHardwareAccelSkiaEnabled(isSkiaHardwareAccelerated());
@@ -321,6 +324,13 @@
         }
     }
 
+    private void setExtraHTTPRequestHeaders(WebSettings settings){
+        String headers = mContext.getResources().getString(R.string.def_extra_http_headers);
+        if (!TextUtils.isEmpty(headers)){
+            settings.setHTTPRequestHeaders(headers);
+        }
+    }
+
     private String constructUserAgent(String userAgent) {
         try {
             userAgent = userAgent.replaceAll("<%build_model>", Build.MODEL);
@@ -778,6 +788,21 @@
         return mPrefs.getBoolean(PREF_ENABLE_MEMORY_MONITOR, true);
     }
 
+    public boolean allowMediaDownloads() {
+        boolean enableMediaDownloads = mController.getContext().getResources().getBoolean(
+                                       R.bool.def_enable_media_downloads);
+        boolean shouldAllowMediaDownloads = mPrefs.getBoolean(
+                                        PREF_ALLOW_MEDIA_DOWNLOADS, enableMediaDownloads);
+
+        if(!mPrefs.contains(PREF_ALLOW_MEDIA_DOWNLOADS)){
+            Editor edit = mPrefs.edit();
+            edit.putBoolean(PREF_ALLOW_MEDIA_DOWNLOADS, shouldAllowMediaDownloads);
+            edit.apply();
+        }
+
+        return shouldAllowMediaDownloads;
+    }
+
     // TODO: Cache
     public ZoomDensity getDefaultZoom() {
         String zoom = mPrefs.getString(PREF_DEFAULT_ZOOM, "MEDIUM");
diff --git a/src/com/android/browser/BrowserWebViewFactory.java b/src/com/android/browser/BrowserWebViewFactory.java
index 9f5e503..f2cfa26 100644
--- a/src/com/android/browser/BrowserWebViewFactory.java
+++ b/src/com/android/browser/BrowserWebViewFactory.java
@@ -68,6 +68,8 @@
         // settings
         final BrowserSettings s = BrowserSettings.getInstance();
         s.startManagingSettings(w.getSettings());
+        if (s.useQuickControls())
+            w.updateTopControls(true, false, false);
     }
 
 }
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index ea1a60c..5f3402f 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -708,10 +708,6 @@
 
         WebView.disablePlatformNotifications();
         NfcHandler.unregister(mActivity);
-        if (sThumbnailBitmap != null) {
-            sThumbnailBitmap.recycle();
-            sThumbnailBitmap = null;
-        }
     }
 
     @Override
@@ -970,6 +966,8 @@
             Performance.onPageFinished(tab.getUrl());
          }
 
+        tab.onPageFinished();
+
         Performance.tracePageFinished();
     }
 
@@ -1838,11 +1836,17 @@
         boolean canGoForward = false;
         boolean isDesktopUa = false;
         boolean isLive = false;
+        // Following flag is used to identify schemes for which the LIVE_MENU
+        // items defined in res/menu/browser.xml should be enabled
+        boolean isLiveScheme = false;
+        boolean isPageFinished = false;
         if (tab != null) {
             canGoBack = tab.canGoBack();
             canGoForward = tab.canGoForward();
             isDesktopUa = mSettings.hasDesktopUseragent(tab.getWebView());
             isLive = !tab.isSnapshot();
+            isLiveScheme = UrlUtils.isLiveScheme(tab.getWebView().getUrl());
+            isPageFinished = tab.getPageFinishedStatus();
         }
         final MenuItem back = menu.findItem(R.id.back_menu_id);
         back.setEnabled(canGoBack);
@@ -1877,8 +1881,9 @@
         boolean showDebugSettings = mSettings.isDebugEnabled();
         final MenuItem uaSwitcher = menu.findItem(R.id.ua_desktop_menu_id);
         uaSwitcher.setChecked(isDesktopUa);
-        menu.setGroupVisible(R.id.LIVE_MENU, isLive);
+        menu.setGroupVisible(R.id.LIVE_MENU, isLive && isLiveScheme);
         menu.setGroupVisible(R.id.SNAPSHOT_MENU, !isLive);
+        menu.setGroupEnabled(R.id.OFFLINE_READING, isLive && isLiveScheme && isPageFinished);
         // history and snapshots item are the members of COMBO menu group,
         // so if show history item, only make snapshots item invisible.
         menu.findItem(R.id.snapshots_menu_id).setVisible(false);
@@ -2143,7 +2148,7 @@
     public void toggleUserAgent() {
         WebView web = getCurrentWebView();
         mSettings.toggleDesktopUseragent(web);
-        web.loadUrl(web.getOriginalUrl());
+        web.reload();
     }
 
     @Override
@@ -2180,7 +2185,11 @@
 
     private void goLive() {
         SnapshotTab t = (SnapshotTab) getCurrentTab();
-        t.loadUrl(t.getLiveUrl(), null);
+        String url = t.getLiveUrl();
+        // destroy the old snapshot tab
+        closeCurrentTab();
+        Tab liveTab =  createNewTab(false, true, false);
+        loadUrl(liveTab, url);
     }
 
     private void showExitDialog(final Activity activity) {
@@ -2480,11 +2489,6 @@
 
         if (sThumbnailBitmap == null || sThumbnailBitmap.getWidth() != width
                    || sThumbnailBitmap.getHeight() != height) {
-            if (sThumbnailBitmap != null) {
-                sThumbnailBitmap.recycle();
-                sThumbnailBitmap = null;
-            }
-
             sThumbnailBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
         }
 
@@ -2509,8 +2513,6 @@
             new ValueCallback<Bitmap>() {
                 @Override
                 public void onReceiveValue(Bitmap bitmap) {
-                    Log.e("sudheer", "screensot bitmap: w: " + bitmap.getWidth()
-                          + " h: " + bitmap.getHeight());
                     if (bitmap != null)
                         bitmap = bitmap.copy(Bitmap.Config.RGB_565, false);
                     cb.onReceiveValue(bitmap);
diff --git a/src/com/android/browser/FetchUrlMimeType.java b/src/com/android/browser/FetchUrlMimeType.java
index 0e8398a..56ea4c3 100644
--- a/src/com/android/browser/FetchUrlMimeType.java
+++ b/src/com/android/browser/FetchUrlMimeType.java
@@ -27,6 +27,8 @@
 import com.android.browser.reflect.ReflectHelper;
 
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 
 import org.apache.http.Header;
 import org.apache.http.HttpHost;
@@ -89,7 +91,17 @@
             client.close();
             return;
         }
-        HttpHead request = new HttpHead(mUri);
+
+        HttpHead request;
+        try {
+            URI uriObj = new URI(mUri);
+            request = new HttpHead(uriObj.toString());
+        } catch (URISyntaxException e) {
+            Log.e(LOGTAG,"Encode URI failed: " + e);
+            client.close();
+            return;
+        }
+
         String cookies = CookieManager.getInstance().getCookie(mUri, mPrivateBrowsing);
         if (cookies != null && cookies.length() > 0) {
             request.addHeader("Cookie", cookies);
diff --git a/src/com/android/browser/LocationButton.java b/src/com/android/browser/LocationButton.java
index 15371ef..e805e43 100644
--- a/src/com/android/browser/LocationButton.java
+++ b/src/com/android/browser/LocationButton.java
@@ -71,8 +71,7 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        //SWE-FIXME : Enable once SWE geolocation api works.
-        //init();
+        init();
     }
 
     private void init() {
diff --git a/src/com/android/browser/NavigationBarBase.java b/src/com/android/browser/NavigationBarBase.java
index a8f52fe..100e8d7 100644
--- a/src/com/android/browser/NavigationBarBase.java
+++ b/src/com/android/browser/NavigationBarBase.java
@@ -75,8 +75,7 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mLockIcon = (ImageView) findViewById(R.id.lock);
-        //SWE-FIXME
-        //mLocationButton = (LocationButton) findViewById(R.id.location_button);
+        mLocationButton = (LocationButton) findViewById(R.id.location_button);
         mFavicon = (ImageView) findViewById(R.id.favicon);
         mUrlInput = (UrlInputView) findViewById(R.id.url);
         mUrlInput.setUrlInputListener(this);
@@ -398,8 +397,7 @@
     }
 
     public void onTabDataChanged(Tab tab) {
-        //SWE-FIXME
-        //mLocationButton.onTabDataChanged(tab);
+        mLocationButton.onTabDataChanged(tab);
     }
 
     public void onVoiceResult(String s) {
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index c789eba..35e6ad3 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -201,6 +201,7 @@
         }
         if (showingNavScreen()) {
             menu.setGroupVisible(R.id.LIVE_MENU, false);
+            menu.setGroupVisible(R.id.OFFLINE_READING, false);
             menu.setGroupVisible(R.id.SNAPSHOT_MENU, false);
             menu.setGroupVisible(R.id.NAV_MENU, false);
             menu.setGroupVisible(R.id.COMBO_MENU, true);
@@ -236,20 +237,12 @@
         super.onActionModeStarted(mode);
         if (!isEditingUrl()) {
             hideTitleBar();
-        } else {
-            TypedValue heightValue = new TypedValue();
-            mBrowser.getTheme().resolveAttribute(
-                android.R.attr.actionBarSize, heightValue, true);
-            int actionBarHeight = TypedValue.complexToDimensionPixelSize(heightValue.data,
-                mBrowser.getResources().getDisplayMetrics());
-            mTitleBar.setTranslationY(actionBarHeight);
         }
     }
 
     @Override
     public void onActionModeFinished(boolean inLoad) {
         super.onActionModeFinished(inLoad);
-        mTitleBar.setTranslationY(0);
         if (inLoad) {
             if (mUseQuickControls) {
                 mTitleBar.setShowProgressOnly(true);
@@ -313,8 +306,7 @@
         int fromLeft = 0;
         int fromTop = getTitleBar().getHeight();
         int fromRight = mContentView.getWidth();
-        int fixedTbarHeight = mTitleBar.isFixed() ? mTitleBar.calculateEmbeddedHeight() : 0;
-        int fromBottom = mContentView.getHeight() + fixedTbarHeight;
+        int fromBottom = mContentView.getHeight();
         int width = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_width);
         int height = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_height);
         int ntth = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_titleheight);
@@ -396,8 +388,9 @@
         if (mAnimScreen == null) {
             mAnimScreen = new AnimScreen(mActivity);
         }
-        int width = mContentView.getWidth();
-        int height = mContentView.getHeight();
+        ImageView target = tabview.mImage;
+        int width = target.getDrawable().getIntrinsicWidth();
+        int height = target.getDrawable().getIntrinsicHeight();
         Bitmap bm = tab.getScreenshot();
         if (bm == null)
             bm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
@@ -405,23 +398,16 @@
         if (mAnimScreen.mMain.getParent() == null) {
             mCustomViewContainer.addView(mAnimScreen.mMain, COVER_SCREEN_PARAMS);
         }
-        int fixedTbarHeight = mTitleBar.isFixed() ? mTitleBar.calculateEmbeddedHeight() : 0;
         mAnimScreen.mMain.layout(0, 0, mContentView.getWidth(),
-                mContentView.getHeight()  + fixedTbarHeight);
+                mContentView.getHeight());
         mNavScreen.mScroller.finishScroller();
-        ImageView target = tabview.mImage;
         int toLeft = 0;
-        int toTop = 0;
-        if (mTitleBar.isFixed()) {
-            toTop = fixedTbarHeight;
-        } else {
-            toTop = (tab.getWebView() != null) ? tab.getWebView().getVisibleTitleHeight() : 0;
-        }
+        int toTop = mTitleBar.calculateEmbeddedHeight();
         int toRight = mContentView.getWidth();
         int fromLeft = tabview.getLeft() + target.getLeft() - mNavScreen.mScroller.getScrollX();
         int fromTop = tabview.getTop() + target.getTop() - mNavScreen.mScroller.getScrollY();
-        int fromRight = fromLeft + target.getDrawable().getIntrinsicWidth();
-        int fromBottom = fromTop + target.getDrawable().getIntrinsicHeight();
+        int fromRight = fromLeft + width;
+        int fromBottom = fromTop + height;
         float scaleFactor = mContentView.getWidth() / (float) width;
         int toBottom = toTop + (int) (height * scaleFactor);
         mAnimScreen.mContent.setLeft(fromLeft);
@@ -546,7 +532,6 @@
         private ImageView mContent;
         private float mScale;
         private Bitmap mTitleBarBitmap;
-        private Bitmap mContentBitmap;
 
         public AnimScreen(Context ctx) {
             mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen,
diff --git a/src/com/android/browser/PreferenceKeys.java b/src/com/android/browser/PreferenceKeys.java
index 73af1f7..83dc371 100644
--- a/src/com/android/browser/PreferenceKeys.java
+++ b/src/com/android/browser/PreferenceKeys.java
@@ -41,6 +41,7 @@
     static final String PREF_DEFAULT_ZOOM = "default_zoom";
     static final String PREF_ENABLE_JAVASCRIPT = "enable_javascript";
     static final String PREF_ENABLE_MEMORY_MONITOR = "enable_memory_monitor";
+    static final String PREF_ALLOW_MEDIA_DOWNLOADS = "allow_media_downloads";
     static final String PREF_LOAD_PAGE = "load_page";
     static final String PREF_OPEN_IN_BACKGROUND = "open_in_background";
     static final String PREF_RESET_DEFAULT_PREFERENCES = "reset_default_preferences";
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 5e71aca..15ebd5e 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -166,6 +166,7 @@
     // If true, the tab is in page loading state (after onPageStarted,
     // before onPageFinsihed)
     private boolean mInPageLoad;
+    private boolean mPageFinished;
     private boolean mDisableOverrideUrlLoading;
     // The last reported progress of the current page
     private int mPageLoadProgress;
@@ -198,7 +199,6 @@
     private int mCaptureWidth;
     private int mCaptureHeight;
     private Bitmap mCapture;
-    private Bitmap mScreenShot;
     private Handler mHandler;
     private boolean mUpdateThumbnail;
     private Timestamp timestamp;
@@ -382,6 +382,7 @@
         @Override
         public void onPageStarted(WebView view, String url, Bitmap favicon) {
             mInPageLoad = true;
+            mPageFinished = false;
             mUpdateThumbnail = true;
             mPageLoadProgress = INITIAL_PROGRESS;
             mCurrentState = new PageState(mContext,
@@ -726,11 +727,25 @@
         mCurrentState.mIncognito = view.isPrivateBrowsingEnabled();
     }
 
+
+    public boolean isTabFullScreen() {
+        return mFullScreen;
+    }
+
     protected void setTabFullscreen(boolean fullScreen) {
-        if (mMainView != null) {
-            mFullScreen = fullScreen;
-            mMainView.setFullScreen(fullScreen);
+        Controller controller = (Controller)mWebViewController;
+
+        if (!mSettings.useFullscreen())
+            controller.getUi().setFullscreen(fullScreen);
+
+        if (getWebView() != null) {
+            if (fullScreen)
+                getWebView().updateTopControls(true, false, true);
+            else if (!mSettings.useQuickControls())
+                getWebView().updateTopControls(true, true, true);
         }
+
+        mFullScreen = fullScreen;
     }
 
     // -------------------------------------------------------------------------
@@ -757,20 +772,17 @@
         @Override
         public void toggleFullscreenModeForTab(boolean enterFullscreen) {
             if (mWebViewController instanceof Controller) {
-                Controller controller = (Controller)mWebViewController;
-                controller.getUi().setFullscreen(enterFullscreen);
                 setTabFullscreen(enterFullscreen);
             }
         }
 
         @Override
-        public void onOffsetsForFullscreenChanged(
-            float topControlsOffsetYPix, float contentOffsetYPix, float overdrawBottomHeightPix) {
-            boolean hide_title_on_scroll =
-                mContext.getResources().getBoolean(R.bool.hide_title_on_scroll);
-            if (mWebViewController instanceof Controller && hide_title_on_scroll) {
+        public void onOffsetsForFullscreenChanged(float topControlsOffsetYPix,
+                                                  float contentOffsetYPix,
+                                                  float overdrawBottomHeightPix) {
+            if (mWebViewController instanceof Controller) {
                 Controller controller = (Controller)mWebViewController;
-                controller.getUi().transalateTitleBar(topControlsOffsetYPix);
+                controller.getUi().translateTitleBar(topControlsOffsetYPix);
             }
         }
 
@@ -1408,10 +1420,6 @@
         }
     }
 
-    public boolean isTabFullScreen() {
-        return mFullScreen;
-    }
-
     /**
      * Destroy the tab's main WebView and subWindow if any
      */
@@ -1459,14 +1467,8 @@
         if (mParent != null) {
             mParent.mChildren.remove(this);
         }
-        if (mScreenShot != null) {
-            mScreenShot.recycle();
-            mScreenShot = null;
-        }
-        if (mCapture != null ) {
-            mCapture.recycle();
-            mCapture = null;
-        }
+
+        mCapture = null;
         deleteThumbnail();
     }
 
@@ -1593,7 +1595,6 @@
     }
 
     void pause() {
-        capture();
         if (mMainView != null) {
             mMainView.onPause();
             if (mSubView != null) {
@@ -1743,6 +1744,15 @@
         return UrlUtils.filteredUrl(mCurrentState.mUrl);
     }
 
+
+    protected void onPageFinished() {
+        mPageFinished = true;
+    }
+
+    public boolean getPageFinishedStatus() {
+        return mPageFinished;
+    }
+
     String getOriginalUrl() {
         if (mCurrentState.mOriginalUrl == null) {
             return getUrl();
@@ -1926,12 +1936,6 @@
         }
     }
 
-    public Bitmap getFullScreenshot() {
-        synchronized (Tab.this) {
-            return mScreenShot;
-        }
-    }
-
     public boolean isSnapshot() {
         return false;
     }
@@ -1966,9 +1970,10 @@
         values.put(Snapshots.BACKGROUND, web.getPageBackgroundColor());
         values.put(Snapshots.DATE_CREATED, System.currentTimeMillis());
         values.put(Snapshots.FAVICON, compressBitmap(getFavicon()));
-        Bitmap screenshot = getScreenshot();
-        if (screenshot != null)
-            values.put(Snapshots.THUMBNAIL, compressBitmap(screenshot));
+        Bitmap screenshot = Controller.createScreenshot(web,
+                Controller.getDesiredThumbnailWidth(mWebViewController.getActivity()),
+                Controller.getDesiredThumbnailHeight(mWebViewController.getActivity()));
+        values.put(Snapshots.THUMBNAIL, compressBitmap(screenshot));
         return values;
     }
 
@@ -1996,7 +2001,13 @@
             }
             return false;
         }
+
         String path = callback.getPath();
+        // could be that saving of file failed
+        if (path == null) {
+            return false;
+        }
+
         File savedFile = new File(path);
         if (!savedFile.exists()) {
            return false;
diff --git a/src/com/android/browser/TabControl.java b/src/com/android/browser/TabControl.java
index 33f60ff..da68b55 100644
--- a/src/com/android/browser/TabControl.java
+++ b/src/com/android/browser/TabControl.java
@@ -318,8 +318,7 @@
         int i = 0;
         for (Tab tab : mTabs) {
             Bundle tabState = tab.saveState();
-            if (tabState != null && tab.getWebView() != null
-                && tab.getWebView().isPrivateBrowsingEnabled() == false) {
+            if (tabState != null && tab.isPrivateBrowsingEnabled() == false) {
                 ids[i++] = tab.getId();
                 String key = Long.toString(tab.getId());
                 if (outState.containsKey(key)) {
diff --git a/src/com/android/browser/TitleBar.java b/src/com/android/browser/TitleBar.java
index 78f2d0e..fa22213 100644
--- a/src/com/android/browser/TitleBar.java
+++ b/src/com/android/browser/TitleBar.java
@@ -114,8 +114,7 @@
     private void setFixedTitleBar() {
         boolean isFixed = !mUseQuickControls
                 && !getContext().getResources().getBoolean(R.bool.hide_title);
-        boolean hide_title_on_scroll =
-            getContext().getResources().getBoolean(R.bool.hide_title_on_scroll);
+
         isFixed |= mAccessibilityManager.isEnabled();
         // If getParent() returns null, we are initializing
         ViewGroup parent = (ViewGroup)getParent();
@@ -127,7 +126,7 @@
         if (parent != null) {
             parent.removeView(this);
         }
-        if (mIsFixedTitleBar && !hide_title_on_scroll) {
+        if (mIsFixedTitleBar) {
             mBaseUi.addFixedTitleBar(this);
         } else {
             mContentView.addView(this, makeLayoutParams());
@@ -148,8 +147,10 @@
         setFixedTitleBar();
         if (use) {
             this.setVisibility(View.GONE);
+            hideTopControls();
         } else {
             this.setVisibility(View.VISIBLE);
+            enableTopControls();
         }
     }
 
@@ -173,12 +174,15 @@
         animator.setDuration(duration);
     }
 
+    //Disable stock autohide behavior in favor of top controls
+    private static final  boolean bOldStyleAutoHideDisabled = true;
     void show() {
         cancelTitleBarAnimation(false);
         if (mUseQuickControls || mSkipTitleBarAnimations) {
             this.setVisibility(View.VISIBLE);
             this.setTranslationY(0);
-        } else {
+            hideTopControls();
+        } else if (!bOldStyleAutoHideDisabled) {
             int visibleHeight = getVisibleTitleHeight();
             float startPos = (-getEmbeddedHeight() + visibleHeight);
             if (getTranslationY() != 0) {
@@ -190,14 +194,16 @@
             setupTitleBarAnimator(mTitleBarAnimator);
             mTitleBarAnimator.start();
         }
+
         mShowing = true;
     }
 
     void hide() {
         if (mUseQuickControls) {
             this.setVisibility(View.GONE);
+            hideTopControls();
         } else {
-            if (mIsFixedTitleBar) return;
+            if (mIsFixedTitleBar || bOldStyleAutoHideDisabled) return;
             if (!mSkipTitleBarAnimations) {
                 cancelTitleBarAnimation(false);
                 int visibleHeight = getVisibleTitleHeight();
@@ -255,10 +261,35 @@
         return webview != null ? webview.getVisibleTitleHeight() : 0;
     }
 
+    private void hideTopControls() {
+        Tab tab = mBaseUi.getActiveTab();
+        WebView view = tab != null ? tab.getWebView() : null;
+        if (view != null)
+            view.updateTopControls(true, false, true);
+    }
+
+    private void showTopControls() {
+        Tab tab = mBaseUi.getActiveTab();
+        WebView view = tab != null ? tab.getWebView() : null;
+        if (view != null)
+            view.updateTopControls(false, true, true);
+    }
+
+    private void enableTopControls() {
+        Tab tab = mBaseUi.getActiveTab();
+        WebView view = tab != null ? tab.getWebView() : null;
+        if (view != null)
+            view.updateTopControls(true, true, true);
+    }
+
+
     /**
      * Update the progress, from 0 to 100.
      */
     public void setProgress(int newProgress) {
+        Tab tab = mBaseUi.getActiveTab();
+        WebView view = tab != null ? tab.getWebView() : null;
+
         if (newProgress >= PROGRESS_MAX) {
             mProgress.setProgress(PageProgressView.MAX_PROGRESS);
             mProgress.setVisibility(View.GONE);
@@ -272,11 +303,26 @@
                     mBaseUi.showTitleBarForDuration();
                 }
             }
+
+            //onPageFinished
+            if (mUseQuickControls) {
+                hideTopControls();
+            } else {
+                enableTopControls();
+            }
+
         } else {
             if (!mInLoad) {
                 mProgress.setVisibility(View.VISIBLE);
                 mInLoad = true;
                 mNavBar.onProgressStarted();
+
+                //onPageStarted
+                if (mUseQuickControls) {
+                    hideTopControls();
+                } else {
+                    showTopControls();
+                }
             }
             mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
                     / PROGRESS_MAX);
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index bf5c5e5..f24f8f3 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -140,7 +140,7 @@
 
     void setUseQuickControls(boolean enabled);
 
-    void transalateTitleBar(float topControlsOffsetYPix);
+    void translateTitleBar(float topControlsOffsetYPix);
 
     public boolean shouldCaptureThumbnails();
 
diff --git a/src/com/android/browser/UrlUtils.java b/src/com/android/browser/UrlUtils.java
index d00e8c3..c327fdc 100755
--- a/src/com/android/browser/UrlUtils.java
+++ b/src/com/android/browser/UrlUtils.java
@@ -24,6 +24,7 @@
 import java.util.regex.Pattern;
 import java.util.HashSet;
 import java.util.Arrays;
+import java.net.URI;
 
 /**
  * Utility methods for Url manipulation
@@ -35,6 +36,14 @@
     private static final HashSet<String> DOWNLOADABLE_SCHEMES =
         new HashSet<String>(Arrays.asList(DOWNLOADABLE_SCHEMES_VALUES));
 
+    // Schemes for which the LIVE_MENU items defined in res/menu/browser.xml
+    // should be enabled
+    public static final String[] LIVE_SCHEMES_VALUES = new String[]
+        { "http", "https" };
+
+    private static final HashSet<String> LIVE_SCHEMES =
+        new HashSet<String>(Arrays.asList(LIVE_SCHEMES_VALUES));
+
     static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
             "(?i)" + // switch on case insensitive matching
             "(" +    // begin group for schema
@@ -102,7 +111,20 @@
 
     public static boolean isDownloadableScheme(String uri) {
         try {
-            return isDownloadableScheme(Uri.parse(uri));
+            URI uriObj = new URI(uri);
+            return isDownloadableScheme(Uri.parse(uriObj.toString()));
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    public static boolean isLiveScheme(Uri uri) {
+        return LIVE_SCHEMES.contains(uri.getScheme());
+    }
+
+    public static boolean isLiveScheme(String uri) {
+        try {
+            return isLiveScheme(Uri.parse(uri));
         } catch (Exception e) {
             return false;
         }
diff --git a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
index 9c96768..e693297 100644
--- a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
+++ b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
@@ -160,15 +160,14 @@
                 }
             }
         });
-        //SWE-FIXME : Uncomment when geolocation is working.
-        /*GeolocationPermissions.getInstance().getOrigins(new ValueCallback<Set<String> >() {
+        GeolocationPermissions.getInstance().getOrigins(new ValueCallback<Set<String> >() {
             @Override
             public void onReceiveValue(Set<String> geolocationOrigins) {
                 if ((geolocationOrigins != null) && !geolocationOrigins.isEmpty()) {
                     websiteSettings.setEnabled(true);
                 }
             }
-        });*/
+        });
     }
 
     @Override
diff --git a/src_system/AndroidManifest.xml b/src_system/AndroidManifest.xml
index 592a34f..0293063 100644
--- a/src_system/AndroidManifest.xml
+++ b/src_system/AndroidManifest.xml
@@ -55,6 +55,7 @@
     <uses-permission android:name="android.permission.VIBRATE"/>
     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
 
     <application   android:name="Browser"
                    android:label="@string/application_name"
@@ -382,6 +383,36 @@
                  android:permission="org.chromium.content_shell.permission.SANDBOX"
                  android:isolatedProcess="true"
                  android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService14"
+                 android:process=":sandboxed_process14"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService15"
+                 android:process=":sandboxed_process15"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService16"
+                 android:process=":sandboxed_process16"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService17"
+                 android:process=":sandboxed_process17"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService18"
+                 android:process=":sandboxed_process18"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
+        <service android:name="org.chromium.content.app.SandboxedProcessService19"
+                 android:process=":sandboxed_process19"
+                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:isolatedProcess="true"
+                 android:exported="false" />
     </application>
 
     <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="19" />