Add dpi support for WebView.

In the "viewport" meta tag, you can specify "target-densityDpi".
If it is not specified, it uses the default, 160dpi as of today.
Then the 1.0 scale factor specified in the viewport tag means 100%
on G1 and 150% on Sholes. If you set "target-densityDpi" to
"device-dpi", then the 1.0 scale factor means 100% on both G1 and Sholes.

Implemented Safari's window.devicePixelRatio and css media query
device-pixel-ratio.

So if you use "device-dpi" and modify the css for font-size and image
src depending on window.devicePixelRatio, you can get a better page on
Sholes/Passion.

Here is a list of options for "target-densityDpi".

device-dpi:    Use the device's native dpi as target dpi.
low-dpi:       120dpi
medium-dpi:    160dpi, which is also the default as of today
high-dpi:      240dpi
<number>:      We take any number between 70 and 400 as a valid target dpi.

Fix http://b/issue?id=2071943
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index a8d2368..9692707 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -412,9 +412,10 @@
     m_viewport_minimum_scale = 0;
     m_viewport_maximum_scale = 0;
     m_viewport_user_scalable = true;
-    m_format_detection_telephone = true;    
-    m_format_detection_address = true;    
-    m_format_detection_email = true;    
+    m_viewport_target_densitydpi = -1;
+    m_format_detection_telephone = true;
+    m_format_detection_address = true;
+    m_format_detection_email = true;
 }
 
 void Settings::setMetadataSettings(const String& key, const String& value)
@@ -465,7 +466,22 @@
         // some sites, e.g. gomoviesapp.com, use "false".
         if (value == "no" || value == "0" || value == "false") {
             m_viewport_user_scalable = false;
-        }        
+        }
+    } else if (key == "target-densitydpi") {
+        if (value == "device-dpi") {
+            m_viewport_target_densitydpi = 0;
+        } else if (value == "low-dpi") {
+            m_viewport_target_densitydpi = 120;
+        } else if (value == "medium-dpi") {
+            m_viewport_target_densitydpi = 160;
+        } else if (value == "high-dpi") {
+            m_viewport_target_densitydpi = 240;
+        } else {
+            int dpi = value.toInt();
+            if (dpi >= 70 && dpi <= 400) {
+                m_viewport_target_densitydpi = dpi;
+            }
+        }
     } else if (key == "telephone") {
         if (value == "no") {
             m_format_detection_telephone = false;
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index 574fed7..162b21d 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -223,12 +223,13 @@
         void resetMetadataSettings();
         void setMetadataSettings(const String& key, const String& value);
 
-        int viewportWidth() const { return m_viewport_width; }        
+        int viewportWidth() const { return m_viewport_width; }
         int viewportHeight() const { return m_viewport_height; }
         int viewportInitialScale() const { return m_viewport_initial_scale; }
         int viewportMinimumScale() const { return m_viewport_minimum_scale; }
         int viewportMaximumScale() const { return m_viewport_maximum_scale; }
         bool viewportUserScalable() const { return m_viewport_user_scalable; }
+        int viewportTargetDensityDpi() const { return m_viewport_target_densitydpi; }
         bool formatDetectionAddress() const { return m_format_detection_address; }
         bool formatDetectionEmail() const { return m_format_detection_email; }
         bool formatDetectionTelephone() const { return m_format_detection_telephone; }
@@ -331,6 +332,9 @@
         int m_viewport_maximum_scale;
         // default is yes
         bool m_viewport_user_scalable : 1;
+        // range is from 70 to 400. 0 is a special value means device-dpi
+        // default is -1, which means undefined.
+        int m_viewport_target_densitydpi;
         // default is yes
         bool m_format_detection_telephone : 1;
         // default is yes
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index 6dc7faf..93869c3 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -81,8 +81,8 @@
 
 float ChromeClientAndroid::scaleFactor()
 {
-    // only seems to be used for dashboard regions, so just return 1
-    return 1;
+    ASSERT(m_webFrame);
+    return m_webFrame->density();
 }
 
 void ChromeClientAndroid::focus() {
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index f366479..f768fd0 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -145,6 +145,7 @@
     jmethodID   mDecidePolicyForFormResubmission;
     jmethodID   mRequestFocus;
     jmethodID   mGetRawResFilename;
+    jmethodID   mDensity;
     AutoJObject frame(JNIEnv* env) {
         return getRealObject(env, mObj);
     }
@@ -200,6 +201,7 @@
             "()V");
     mJavaFrame->mGetRawResFilename = env->GetMethodID(clazz, "getRawResFilename",
             "(I)Ljava/lang/String;");
+    mJavaFrame->mDensity = env->GetMethodID(clazz, "density","()F");
 
     LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource");
     LOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted");
@@ -218,6 +220,7 @@
     LOG_ASSERT(mJavaFrame->mDecidePolicyForFormResubmission, "Could not find method decidePolicyForFormResubmission");
     LOG_ASSERT(mJavaFrame->mRequestFocus, "Could not find method requestFocus");
     LOG_ASSERT(mJavaFrame->mGetRawResFilename, "Could not find method getRawResFilename");
+    LOG_ASSERT(mJavaFrame->mDensity, "Could not find method density");
 
     mUserAgent = WebCore::String();
     mUserInitiatedClick = false;
@@ -715,6 +718,15 @@
     return to_string(env, ret);
 }
 
+float
+WebFrame::density() const
+{
+    JNIEnv* env = JSC::Bindings::getJNIEnv();
+    jfloat dpi = env->CallFloatMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDensity);
+    checkException(env);
+    return dpi;
+}
+
 // ----------------------------------------------------------------------------
 static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision)
 {
diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h
index 353545e..609aecc 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.h
+++ b/WebKit/android/jni/WebCoreFrameBridge.h
@@ -109,6 +109,8 @@
 
     WebCore::String getRawResourceFilename(RAW_RES_ID) const;
 
+    float density() const;
+
     /**
      * When the user initiates a click (via trackball, enter-press, or touch),
      * we set mUserInitiatedClick to true.  If a load happens due to this click,
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index dc51a8f..07e7633 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -148,6 +148,7 @@
     jfieldID    m_viewportMinimumScale;
     jfieldID    m_viewportMaximumScale;
     jfieldID    m_viewportUserScalable;
+    jfieldID    m_viewportDensityDpi;
     jfieldID    m_webView;
 } gWebViewCoreFields;
 
@@ -2557,6 +2558,7 @@
     env->SetIntField(obj, gWebViewCoreFields.m_viewportMinimumScale, s->viewportMinimumScale());
     env->SetIntField(obj, gWebViewCoreFields.m_viewportMaximumScale, s->viewportMaximumScale());
     env->SetBooleanField(obj, gWebViewCoreFields.m_viewportUserScalable, s->viewportUserScalable());
+    env->SetIntField(obj, gWebViewCoreFields.m_viewportDensityDpi, s->viewportTargetDensityDpi());
 #endif
 }
 
@@ -2841,6 +2843,10 @@
             "mViewportUserScalable", "Z");
     LOG_ASSERT(gWebViewCoreFields.m_viewportUserScalable,
             "Unable to find android/webkit/WebViewCore.mViewportUserScalable");
+    gWebViewCoreFields.m_viewportDensityDpi = env->GetFieldID(widget,
+            "mViewportDensityDpi", "I");
+    LOG_ASSERT(gWebViewCoreFields.m_viewportDensityDpi,
+            "Unable to find android/webkit/WebViewCore.mViewportDensityDpi");
     gWebViewCoreFields.m_webView = env->GetFieldID(widget,
             "mWebView", "Landroid/webkit/WebView;");
     LOG_ASSERT(gWebViewCoreFields.m_webView,