Initial implementation of the useragent switcher

Change-Id: Iaa8262a678902645dbfaa8a53fe7212af7d9d53c
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index e6bd759..dd46314 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -46,6 +46,7 @@
 import java.lang.ref.WeakReference;
 import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.WeakHashMap;
 
 /**
  * Class for managing settings
@@ -90,6 +91,7 @@
     private Controller mController;
     private WebStorageSizeManager mWebStorageSizeManager;
     private AutofillHandler mAutofillHandler;
+    private WeakHashMap<WebSettings, String> mCustomUserAgents;
 
     // Cached settings
     private SearchEngine mSearchEngine;
@@ -111,6 +113,7 @@
         }
         mAutofillHandler = new AutofillHandler(mContext);
         mManagedSettings = new LinkedList<WeakReference<WebSettings>>();
+        mCustomUserAgents = new WeakHashMap<WebSettings, String>();
         mWebStorageSizeManager = new WebStorageSizeManager(mContext,
                 new WebStorageSizeManager.StatFsDiskInfo(getAppCachePath()),
                 new WebStorageSizeManager.WebKitAppCacheInfo(getAppCachePath()));
@@ -151,7 +154,6 @@
         settings.setForceUserScalable(forceEnableUserScalable());
         settings.setPluginState(getPluginState());
         settings.setTextSize(getTextSize());
-        settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
         settings.setAutoFillEnabled(isAutofillEnabled());
         settings.setLayoutAlgorithm(getLayoutAlgorithm());
         settings.setJavaScriptCanOpenWindowsAutomatically(blockPopupWindows());
@@ -161,6 +163,13 @@
         settings.setSaveFormData(saveFormdata());
         settings.setUseWideViewPort(isWideViewport());
         settings.setAutoFillProfile(getAutoFillProfile());
+
+        String ua = mCustomUserAgents.get(settings);
+        if (enableUseragentSwitcher() && ua != null) {
+            settings.setUserAgentString(ua);
+        } else {
+            settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
+        }
     }
 
     /**
@@ -385,6 +394,21 @@
         setDebugEnabled(!isDebugEnabled());
     }
 
+    public boolean hasDesktopUseragent(WebView view) {
+        return view != null && mCustomUserAgents.get(view.getSettings()) != null;
+    }
+
+    public void toggleDesktopUseragent(WebView view) {
+        WebSettings settings = view.getSettings();
+        if (mCustomUserAgents.get(settings) != null) {
+            mCustomUserAgents.remove(settings);
+            settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
+        } else {
+            mCustomUserAgents.put(settings, DESKTOP_USERAGENT);
+            settings.setUserAgentString(DESKTOP_USERAGENT);
+        }
+    }
+
     // -----------------------------
     // getter/setters for accessibility_preferences.xml
     // -----------------------------
@@ -579,6 +603,10 @@
         return mPrefs.getBoolean(PREF_FULLSCREEN, false);
     }
 
+    public boolean enableUseragentSwitcher() {
+        return mPrefs.getBoolean(PREF_ENABLE_USERAGENT_SWITCHER, false);
+    }
+
     // -----------------------------
     // getter/setters for privacy_security_preferences.xml
     // -----------------------------
diff --git a/src/com/android/browser/PreferenceKeys.java b/src/com/android/browser/PreferenceKeys.java
index f7230df..cff9f70 100644
--- a/src/com/android/browser/PreferenceKeys.java
+++ b/src/com/android/browser/PreferenceKeys.java
@@ -78,6 +78,7 @@
     static final String PREF_USE_MOST_VISITED_HOMEPAGE = "use_most_visited_homepage";
     static final String PREF_USE_INSTANT_SEARCH = "use_instant_search";
     static final String PREF_FULLSCREEN = "fullscreen";
+    static final String PREF_ENABLE_USERAGENT_SWITCHER = "enable_useragent_switcher";
 
     // ----------------------
     // Keys for privacy_security_preferences.xml
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index 567b35a..8c03e4c 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -20,9 +20,12 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
+import android.preference.PreferenceManager;
 import android.text.TextUtils;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -59,6 +62,8 @@
     private ImageView mVoiceSearch;
     private Drawable mFocusDrawable;
     private Drawable mUnfocusDrawable;
+    private boolean mHasFocus = false;
+    private BrowserSettings mSettings;
 
     public TitleBarXLarge(Activity activity, UiController controller,
             XLargeUi ui, FrameLayout parent) {
@@ -72,7 +77,10 @@
         mUnfocusDrawable = resources.getDrawable(
                 R.drawable.textfield_default_holo_dark);
         mInVoiceMode = false;
+        mSettings = BrowserSettings.getInstance();
         initLayout(activity, R.layout.url_bar);
+        PreferenceManager.getDefaultSharedPreferences(activity)
+                .registerOnSharedPreferenceChangeListener(mSharedPrefsListener);
     }
 
     @Override
@@ -101,6 +109,7 @@
         mGoButton.setOnClickListener(this);
         mClearButton.setOnClickListener(this);
         mVoiceSearch.setOnClickListener(this);
+        mUrlIcon.setOnClickListener(this);
         mUrlInput.setContainer(mUrlContainer);
         setFocusState(false);
     }
@@ -115,6 +124,7 @@
                     ? R.drawable.ic_forward_holo_dark
                     : R.drawable.ic_forward_disabled_holo_dark);
         }
+        updateUrlIcon();
     }
 
     @Override
@@ -177,6 +187,13 @@
             clearOrClose();
         } else if (mVoiceSearch == v) {
             mUiController.startVoiceSearch();
+        } else if (mUrlIcon == v) {
+            WebView web = mUiController.getCurrentWebView();
+            if (mSettings.enableUseragentSwitcher() && web != null) {
+                mSettings.toggleDesktopUseragent(web);
+                web.loadUrl(web.getOriginalUrl());
+                updateUrlIcon();
+            }
         } else {
             super.onClick(v);
         }
@@ -195,9 +212,39 @@
         }
     }
 
+    void updateUrlIcon() {
+        if (mHasFocus) {
+            return;
+        }
+        if (!mInVoiceMode && mSettings.enableUseragentSwitcher()) {
+            WebView web = mUiController.getCurrentWebView();
+            if (mSettings.hasDesktopUseragent(web)) {
+                mUrlIcon.setImageResource(R.drawable.ic_ua_desktop);
+            } else {
+                mUrlIcon.setImageResource(R.drawable.ic_ua_android);
+            }
+        } else {
+            mUrlIcon.setImageResource(mInVoiceMode ?
+                    R.drawable.ic_search_holo_dark
+                    : R.drawable.ic_web_holo_dark);
+        }
+    }
+
+    private OnSharedPreferenceChangeListener mSharedPrefsListener =
+            new OnSharedPreferenceChangeListener() {
+
+        @Override
+        public void onSharedPreferenceChanged(
+                SharedPreferences sharedPreferences, String key) {
+            updateUrlIcon();
+        }
+
+    };
+
     @Override
     protected void setFocusState(boolean focus) {
         super.setFocusState(focus);
+        mHasFocus = focus;
         if (focus) {
             mSearchButton.setVisibility(View.GONE);
             mStar.setVisibility(View.GONE);
@@ -214,9 +261,7 @@
             } else {
                 mSearchButton.setVisibility(View.VISIBLE);
             }
-            mUrlIcon.setImageResource(mInVoiceMode ?
-                    R.drawable.ic_search_holo_dark
-                    : R.drawable.ic_web_holo_dark);
+            updateUrlIcon();
         }
     }