From fd0ffdd855f7192941bfecb2276dd4672f575007 Mon Sep 17 00:00:00 2001
From: Danny Baumann <dannybaumann@web.de>
Date: Thu, 18 May 2017 11:04:40 +0200
Subject: [PATCH 01/12] Add support for getting updates for theme color
 changes.

---
 .../webview/chromium/WebViewChromium.java     |  8 +++++
 .../WebViewContentsClientAdapter.java         | 34 +++++++++++++++++++
 .../android_webview/AwContentsClient.java     |  2 ++
 .../AwContentsClientCallbackHelper.java       | 12 +++++++
 .../AwWebContentsObserver.java                | 14 ++++++++
 .../test/NullContentsClient.java              |  4 +++
 6 files changed, 74 insertions(+)

diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
index a62479ecded64..902336b897353 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -86,6 +86,7 @@ import org.chromium.components.embedder_support.application.ClassLoaderContextWr
 import org.chromium.content_public.browser.MessagePayload;
 import org.chromium.content_public.browser.NavigationHistory;
 import org.chromium.content_public.browser.SmartClipProvider;
+import org.chromium.content_public.browser.WebContents;
 import org.chromium.url.GURL;
 
 import java.io.BufferedWriter;
@@ -1824,6 +1825,13 @@ class WebViewChromium
         }
     }
 
+    public int getThemeColor() {
+        WebContents webContents = mAwContents != null ? mAwContents.getWebContents() : null;
+        if (webContents == null) return Color.TRANSPARENT;
+        // No checkThread() because the value is cached java side (workaround for b/10533304).
+        return webContents.getThemeColor();
+    }
+
     @Override
     public int getContentHeight() {
         try (TraceEvent event = TraceEvent.scoped("WebView.APICall.Framework.GET_CONTENT_HEIGHT")) {
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
index a76418fcec396..1dcafd344872f 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
@@ -63,6 +63,8 @@ import org.chromium.components.embedder_support.util.WebResourceResponseInfo;
 import org.chromium.content_public.browser.util.DialogTypeRecorder;
 
 import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.security.Principal;
 import java.security.PrivateKey;
 import java.security.cert.X509Certificate;
@@ -106,6 +108,9 @@ class WebViewContentsClientAdapter extends SharedWebViewContentsClientAdapter {
     private WeakHashMap<AwPermissionRequest, WeakReference<PermissionRequestAdapter>>
             mOngoingPermissionRequests;
 
+    private static Method sWebChromeClientThemeColorMethod;
+    private static boolean sWebChromeClientThemeColorMethodInitialized;
+
     /**
      * Adapter constructor.
      *
@@ -117,6 +122,17 @@ class WebViewContentsClientAdapter extends SharedWebViewContentsClientAdapter {
         super(webView, webViewDelegate, context);
         try (ScopedSysTraceEvent event =
                 ScopedSysTraceEvent.scoped("WebView.APICallback.WebViewClient.constructor")) {
+
+            if (!sWebChromeClientThemeColorMethodInitialized) {
+                try {
+                    sWebChromeClientThemeColorMethod = WebChromeClient.class.getMethod(
+                            "onThemeColorChanged", WebView.class, Integer.TYPE);
+                } catch (Exception e) {
+                    // ignored
+                }
+                sWebChromeClientThemeColorMethodInitialized = true;
+            }
+
             // See //android_webview/docs/how-does-on-create-window-work.md for more details.
             mUiThreadHandler =
                     new Handler() {
@@ -1083,6 +1099,24 @@ class WebViewContentsClientAdapter extends SharedWebViewContentsClientAdapter {
         }
     }
 
+    /**
+     * @see AwContentsClient#onThemeColorChanged(int)
+     */
+    @Override
+    public void onThemeColorChanged(int color) {
+        try {
+            TraceEvent.begin("WebViewContentsClientAdapter.onThemeColorChanged");
+            if (mWebChromeClient != null && sWebChromeClientThemeColorMethod != null) {
+                if (TRACE) Log.d(TAG, "onThemeColorChanged=" + color);
+                sWebChromeClientThemeColorMethod.invoke(mWebChromeClient, mWebView, color);
+            }
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            // ignored
+        } finally {
+            TraceEvent.end("WebViewContentsClientAdapter.onThemeColorChanged");
+        }
+    }
+
     private static class AwHttpAuthHandlerAdapter extends android.webkit.HttpAuthHandler {
         private final AwHttpAuthHandler mAwHandler;
 
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
index 87c0f6aec84b7..60db71f28c915 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
@@ -144,6 +144,8 @@ public abstract class AwContentsClient {
 
     public abstract void onProgressChanged(int progress);
 
+    public abstract void onThemeColorChanged(int color);
+
     public abstract WebResourceResponseInfo shouldInterceptRequest(AwWebResourceRequest request);
 
     public abstract boolean shouldOverrideKeyEvent(KeyEvent event);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClientCallbackHelper.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClientCallbackHelper.java
index 96f87025ed2e3..553ff1276c03f 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClientCallbackHelper.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClientCallbackHelper.java
@@ -138,6 +138,9 @@ public class AwContentsClientCallbackHelper {
     private static final int MSG_ON_FORM_RESUBMISSION = 14;
     private static final int MSG_ON_SAFE_BROWSING_HIT = 15;
 
+    // Custom
+    private static final int MSG_ON_THEME_COLOR_CHANGED = 99;
+
     // Minimum period allowed between consecutive onNewPicture calls, to rate-limit the callbacks.
     private static final long ON_NEW_PICTURE_MIN_PERIOD_MILLIS = 500;
     // Timestamp of the most recent onNewPicture callback.
@@ -272,6 +275,11 @@ public class AwContentsClientCallbackHelper {
                         mContentsClient.onFormResubmission(info.mDontResend, info.mResend);
                         break;
                     }
+                case MSG_ON_THEME_COLOR_CHANGED:
+                    {
+                        mContentsClient.onThemeColorChanged(msg.arg1);
+                        break;
+                    }
                 default:
                     throw new IllegalStateException(
                             "AwContentsClientCallbackHelper: unhandled message " + msg.what);
@@ -376,6 +384,10 @@ public class AwContentsClientCallbackHelper {
         mHandler.sendMessage(mHandler.obtainMessage(MSG_SYNTHESIZE_PAGE_LOADING, url));
     }
 
+    public void postOnThemeColorChanged(int color) {
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_THEME_COLOR_CHANGED, color, 0));
+    }
+
     public void postDoUpdateVisitedHistory(String url, boolean isReload) {
         DoUpdateVisitedHistoryInfo info = new DoUpdateVisitedHistoryInfo(url, isReload);
         mHandler.sendMessage(mHandler.obtainMessage(MSG_DO_UPDATE_VISITED_HISTORY, info));
diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
index ea85bdc646907..bd251ff0ead85 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
@@ -321,6 +321,13 @@ public class AwWebContentsObserver extends WebContentsObserver
                     });
         }
 
+        if (client != null) {
+            WebContents contents = awContents != null ? awContents.getWebContents() : null;
+            if (contents != null) {
+                client.getCallbackHelper().postOnThemeColorChanged(contents.getThemeColor());
+            }
+        }
+
         if (client != null && navigation.isPrimaryMainFrameFragmentNavigation()) {
             // Note fragment navigations do not have a matching onPageStarted.
             client.getCallbackHelper().postOnPageFinished(url);
@@ -347,6 +354,13 @@ public class AwWebContentsObserver extends WebContentsObserver
         }
     }
 
+    public void didChangeThemeColor(int color) {
+        AwContentsClient client = mAwContentsClient.get();
+        if (client != null) {
+            client.getCallbackHelper().postOnThemeColorChanged(color);
+        }
+    }
+
     public boolean didEverCommitNavigation() {
         return mCommittedNavigation;
     }
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java b/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java
index 3ece9777e66ad..8649247f79f19 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java
@@ -70,6 +70,10 @@ public class NullContentsClient extends AwContentsClient {
     @Override
     public void onProgressChanged(int progress) {}
 
+    @Override
+    public void onThemeColorChanged(int color) {
+    }
+
     @Override
     public WebResourceResponseInfo shouldInterceptRequest(AwWebResourceRequest request) {
         return null;
-- 
2.51.2

