当前位置: 首页 > 工具软件 > Std UI Kit > 使用案例 >

android browser 的几个小feature (四) kitkat上实现UaProfile的设置

方苗宣
2023-12-01

在Browser的app里面,为了方便测试,就先简单写了一个例子。

--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -272,6 +272,8 @@ public class BrowserSettings implements OnSharedPreferenceChangeListener,
         } else {
             settings.setUserAgentString(USER_AGENTS[getUserAgent()]);
         }
+       String uaprofile = "www.baidu.com";
+       settings.setUserProfileString(uaprofile);
     }
UaProfile一般为一个xml的网页,存放在运营商的服务器上。我们这边先以www.baidu.com来代替
然后修改的就是framework的部分了,framework/base中的webkit中,我们写了两个方法分别是get和set Profile
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 98ef66e..4e273f9 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -599,6 +599,9 @@ public abstract class WebSettings {
         throw new MustOverrideException();
     }

+    /** {@hide} */
+    public synchronized void setUserProfile(int ua) {
+    }
     /**
      * Gets the user-agent as an integer code.
      * <ul>
@@ -1332,6 +1335,16 @@ public abstract class WebSettings {
         throw new MustOverrideException();
     }

+    /** {@hide} */
+    public synchronized void setUserProfileString(String ua){
+       throw new MustOverrideException();
+    }
+
+    /** {@hide} */
+    public synchronized String getUserProfileString()
+    {
+        throw new MustOverrideException();
+    }
     /**
      * Gets the WebView's user-agent string.
      *
在framework的webview中,我们也需要重新对websettings里面的方法进行重写。
--- a/chromium/java/com/android/webview/chromium/ContentSettingsAdapter.java
+++ b/chromium/java/com/android/webview/chromium/ContentSettingsAdapter.java
@@ -200,6 +200,16 @@ public class ContentSettingsAdapter extends android.webkit.WebSettings {
     }

     @Override
+    public synchronized void setUserProfile(int ua)
+    {
+        if (ua == 0) {
+            setUserProfileString(null);
+        } else {
+            Log.d("chao","setUserProfile not supported, ua=" + ua);
+        }
+    }
+
+    @Override
     public synchronized int getUserAgent() {
         // Minimal implementation for backwards compatibility: just identifies default vs custom.
         return AwSettings.getDefaultUserAgent().equals(getUserAgentString()) ? 0 : -1;
@@ -511,6 +521,16 @@ public class ContentSettingsAdapter extends android.webkit.WebSettings {
     }

     @Override
+    public synchronized void setUserProfileString(String ua) {
+        mAwSettings.setUserProfileString(ua);
+    }
+
+    @Override
+    public synchronized String getUserProfileString() {
+       return mAwSettings.getUserProfileString();
+    }
+
+    @Override
     public synchronized String getUserAgentString() {
         return mAwSettings.getUserAgentString();
     }
接下来修改的是extern/chromium_org中的部分了。
先是android_webview中的java部分,这部分可以和framework中进行互相调用。
--- a/android_webview/java/src/org/chromium/android_webview/AwSettings.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
@@ -14,7 +14,7 @@ import android.provider.Settings;
 import android.webkit.WebSettings.PluginState;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
-
+import android.util.Log;
 import org.chromium.base.CalledByNative;
 import org.chromium.base.JNINamespace;
 import org.chromium.base.ThreadUtils;
@@ -64,6 +64,7 @@ public class AwSettings {
     // TODO(mnaganov): Should be obtained from Android. Problem: it is hidden.
     private String mDefaultTextEncoding = "Latin-1";
     private String mUserAgent;
+    private String mUserProfile;
     private int mMinimumFontSize = 8;
     private int mMinimumLogicalFontSize = 8;
     private int mDefaultFontSize = 16;
@@ -373,7 +374,6 @@ public class AwSettings {
     private float getInitialPageScalePercentLocked() {
         return mInitialPageScalePercent;
     }
-
     /**
      * See {@link android.webkit.WebSettings#setNeedInitialFocus}.
      */
@@ -469,6 +469,36 @@ public class AwSettings {
     }

     /**
+     * Add by chao
+     */
+    public void setUserProfileString(String ua)
+    {
+        synchronized (mAwSettingsLock) {
+            mUserProfile = ua;
+            Log.e("chao","setUserProfileString ua = " + ua);
+           mEventHandler.maybeRunOnUiThreadBlocking(new Runnable() {
+                @Override
+                public void run() {
+                   if (mNativeAwSettings != 0) {
+                        nativeUpdateUserProfileLocked(mNativeAwSettings);
+                    }
+                }
+            });
+        }
+    }
+
+    public String getUserProfileString() {
+        synchronized (mAwSettingsLock) {
+            return mUserProfile;
+        }
+    }
+
+    @CalledByNative
+    private String getUserProfileLocked() {
+        return mUserProfile;
+    }
+
+    /**
      * See {@link android.webkit.WebSettings#getUserAgentString}.
      */
     public String getUserAgentString() {
@@ -1410,6 +1440,7 @@ public class AwSettings {

     private native void nativeUpdateInitialPageScaleLocked(int nativeAwSettings);

+    private native void nativeUpdateUserProfileLocked(int nativeAwSettings);
     private native void nativeUpdateUserAgentLocked(int nativeAwSettings);

     private native void nativeUpdateWebkitPreferencesLocked(int nativeAwSettings);
在java端的部分处理完之后,可以对native的部分进行修改了。
于AwSettings.java相对应的部分是aw_settings.cc了。
diff --git a/android_webview/native/aw_settings.cc b/android_webview/native/aw_settings.cc
index e4aa588..a8863e2 100644
--- a/android_webview/native/aw_settings.cc
+++ b/android_webview/native/aw_settings.cc
@@ -100,10 +100,29 @@ void AwSettings::UpdateEverythingLocked(JNIEnv* env, jobject obj) {
   UpdateInitialPageScaleLocked(env, obj);
   UpdateWebkitPreferencesLocked(env, obj);
   UpdateUserAgentLocked(env, obj);
+  UpdateUserProfileLocked(env, obj);
   ResetScrollAndScaleState(env, obj);
   UpdateFormDataPreferencesLocked(env, obj);
 }

+void AwSettings::UpdateUserProfileLocked(JNIEnv* env, jobject obj) {
+  if (!web_contents()) return;
+  ScopedJavaLocalRef<jstring> str =
+      Java_AwSettings_getUserProfileLocked(env, obj);
+  bool uaprofile_overidden = str.obj() != NULL;
+  LOG(ERROR) << "chao  uaprofile_overidden = " << uaprofile_overidden;
+  if (uaprofile_overidden) {
+    std::string override = base::android::ConvertJavaStringToUTF8(str);
+    LOG(ERROR) << "chao  override = " << override;
+    web_contents()->SetUserProfileOverride(override);
+  }
+}
 void AwSettings::UpdateUserAgentLocked(JNIEnv* env, jobject obj) {
   if (!web_contents()) return;
因为是c文件,所以要给我们新添加的文件进行声明。
diff --git a/android_webview/native/aw_settings.h b/android_webview/native/aw_settings.h
index d1f81c3..e52adec 100644
--- a/android_webview/native/aw_settings.h
+++ b/android_webview/native/aw_settings.h
@@ -32,6 +32,7 @@ class AwSettings : public content::WebContentsObserver {
   void UpdateEverythingLocked(JNIEnv* env, jobject obj);
   void UpdateInitialPageScaleLocked(JNIEnv* env, jobject obj);
   void UpdateUserAgentLocked(JNIEnv* env, jobject obj);
+  void UpdateUserProfileLocked(JNIEnv* env, jobject obj);
   void UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj);
   void UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj);
因为我们的方法是用web_contents()->SetUserProfileOverride(override)去进行相应的实现,所以我们还需要修改相应的文件。
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 8f09208..21070ec 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -863,6 +863,29 @@ WebUI* WebContentsImpl::GetCommittedWebUI() const {
   return render_manager_.web_ui();
 }

+void WebContentsImpl::SetUserProfileOverride(const std::string& override) {
+  LOG(ERROR) << "chao override = " << override;
+  WebPreferences prefs;
+  prefs.user_profile_override = override;
+  GURL url = controller_.GetActiveEntry()
+      ? controller_.GetActiveEntry()->GetURL() : GURL::EmptyGURL();
+  GetContentClient()->browser()->OverrideWebkitPrefs(host, url, &prefs);
+}

void WebContentsImpl::SetUserAgentOverride(const std::string& override) {
   if (GetUserAgentOverride() == override)
     return;
同样的,声明是必不可少的。
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index a5eaf7d..f833e8c 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -229,6 +229,8 @@ class CONTENT_EXPORT WebContentsImpl
   virtual WebUI* GetCommittedWebUI() const OVERRIDE;
   virtual void SetUserAgentOverride(const std::string& override) OVERRIDE;
   virtual const std::string& GetUserAgentOverride() const OVERRIDE;
+  virtual void SetUserProfileOverride(const std::string& override) OVERRIDE;
 #if defined(OS_WIN) && defined(USE_AURA)
   virtual void SetParentNativeViewAccessible(
       gfx::NativeViewAccessible accessible_parent) OVERRIDE;
因为是继承的关系,所以还要在其父类中进行声明。
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 86b51a2..b09a8c8 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -210,6 +210,8 @@ class WebContents : public PageNavigator,

   // Allows overriding the user agent used for NavigationEntries it owns.
   virtual void SetUserAgentOverride(const std::string& override) = 0;
+  virtual void SetUserProfileOverride(const std::string& override) = 0;
   virtual const std::string& GetUserAgentOverride() const = 0;

 #if defined(OS_WIN) && defined(USE_AURA)
我们是利用webPrefrence作为中介,所以我们在webpreferences中要对相应的内容进行声明。这里,由于只有这一个对象,所以我们必须使用static变量来进行声明。
diff --git a/webkit/common/webpreferences.cc b/webkit/common/webpreferences.cc
index 02a87df..409a549 100644
--- a/webkit/common/webpreferences.cc
+++ b/webkit/common/webpreferences.cc
@@ -12,6 +12,7 @@

 using WebKit::WebSettings;

+std::string WebPreferences::user_profile_override = "";
 WebPreferences::WebPreferences()
     : default_font_size(16),
       default_fixed_font_size(13),
@@ -154,6 +155,7 @@ WebPreferences::WebPreferences()
       ASCIIToUTF16("Times New Roman");
 }

+
 WebPreferences::~WebPreferences() {
 }

diff --git a/webkit/common/webpreferences.h b/webkit/common/webpreferences.h
index d94ec9c..e2d44cb 100644
--- a/webkit/common/webpreferences.h
+++ b/webkit/common/webpreferences.h
@@ -18,7 +18,6 @@
 #include "base/strings/string16.h"
 #include "url/gurl.h"
 #include "webkit/common/webkit_common_export.h"
-
 namespace WebKit {
 class WebView;
 }
@@ -79,6 +78,7 @@ struct WEBKIT_COMMON_EXPORT WebPreferences {
   bool remote_fonts_enabled;
   bool javascript_can_access_clipboard;
   bool xss_auditor_enabled;
+  static std::string user_profile_override;
   // We don't use dns_prefetching_enabled to disable DNS prefetching.  Instead,
   // we disable the feature at a lower layer so that we catch non-WebKit uses
   // of DNS prefetch as well.
在thirdparty的webkit中,我们要开始使用这个一直传递过来的值进行赋值。
diff --git a/Source/core/loader/FrameLoader.cpp b/Source/core/loader/FrameLoader.cpp
index f068e20..c7399dc 100644
--- a/Source/core/loader/FrameLoader.cpp
+++ b/Source/core/loader/FrameLoader.cpp
@@ -34,7 +34,6 @@

 #include "config.h"
 #include "core/loader/FrameLoader.h"
-
 #include "HTMLNames.h"
 #include "bindings/v8/DOMWrapperWorld.h"
 #include "bindings/v8/ScriptController.h"
@@ -90,7 +89,10 @@
 #include "wtf/TemporaryChange.h"
 #include "wtf/text/CString.h"
 #include "wtf/text/WTFString.h"
-
+#include <iostream>
+#include "../../../../../webkit/common/webpreferences.h"
+#include "public/platform/WebString.h"
+#include <string>
 namespace WebCore {

 using namespace HTMLNames;
@@ -1316,6 +1318,17 @@ int FrameLoader::numPendingOrLoadingRequests(bool recurse) const
     return count;
 }

+String FrameLoader::userProfile(const KURL& url) const
+{
+     WebPreferences prefs;
+
+    std::string userProfile = prefs.user_profile_override;
+    String tmp_Profile = WebKit::WebString::fromUTF8(userProfile);
+    LOG_ERROR("chao userProfile");
+    LOG_ERROR("chao userProfile = %s", userProfile);
+    return tmp_Profile;
+}
+
 String FrameLoader::userAgent(const KURL& url) const
 {
     String userAgent = m_client->userAgent(url);

@@ -1378,7 +1394,8 @@ void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request)
         return;

     applyUserAgent(request);
-
+    LOG_ERROR("chao applyUserProfile  begin");
+    applyUserProfile(request);
     if (request.cachePolicy() == ReloadIgnoringCacheData) {
         if (m_loadType == FrameLoadTypeReload)
             request.setHTTPHeaderField("Cache-Control", "max-age=0");
@@ -1395,6 +1412,21 @@ void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request)
     addHTTPOriginIfNeeded(request, String());
 }

+
+void FrameLoader::applyUserProfile(ResourceRequest& request)
+{
+    String userProfile = this->userProfile(request.url());
+    LOG_ERROR("chao FrameLoader::applyUserProfile userProfile = %s",userProfile);
+    request.setHTTPUaProfile(userProfile);
+}
+
+
 void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, const String& origin)
 {
     if (!request.httpOrigin().isEmpty())
相关新增函数的声明:
diff --git a/Source/core/loader/FrameLoader.h b/Source/core/loader/FrameLoader.h
index c9ff319..c40f568 100644
--- a/Source/core/loader/FrameLoader.h
+++ b/Source/core/loader/FrameLoader.h
@@ -182,7 +182,7 @@ public:
     void receivedFirstData();

     String userAgent(const KURL&) const;
-
+    String userProfile(const KURL&) const;
     void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*);
     void dispatchDidClearWindowObjectsInAllWorlds();
     void dispatchDocumentElementAvailable();
@@ -218,6 +218,8 @@ public:
     Frame* findFrameForNavigation(const AtomicString& name, Document* activeDocument = 0);

     void applyUserAgent(ResourceRequest&);
+    void applyUserProfile(ResourceRequest& request);

     bool shouldInterruptLoadForXFrameOptions(const String&, const KURL&, unsigned long requestIdentifier);
然后就是这个函数的实现:
diff --git a/Source/core/platform/network/ResourceRequest.h b/Source/core/platform/network/ResourceRequest.h
index d54305a..7062960 100644
--- a/Source/core/platform/network/ResourceRequest.h
+++ b/Source/core/platform/network/ResourceRequest.h
@@ -145,7 +145,7 @@ namespace WebCore {
         String httpUserAgent() const { return httpHeaderField("User-Agent"); }
         void setHTTPUserAgent(const String& httpUserAgent) { setHTTPHeaderField("User-Agent", httpUserAgent); }
         void clearHTTPUserAgent();
-
+        void setHTTPUaProfile(const String& httpUAProfile) { setHTTPHeaderField("x-wap-profile", httpUAProfile); }
         String httpAccept() const { return httpHeaderField("Accept"); }
         void setHTTPAccept(const String& httpAccept) { setHTTPHeaderField("Accept", httpAccept); }
         void clearHTTPAccept();
 类似资料: