MD5 校验值:c9acc583577d8b1a394e7959c947bec3
SafeDKWebAppInterface.java 文件包含反编译后的源代码,请注意,该内容仅供学习和参考使用,不得用于非法用途。
package com.safedk.android.internal; import android.content.Context; import android.os.Build; import android.webkit.JavascriptInterface; import android.webkit.WebView; import com.safedk.android.SafeDK; import com.safedk.android.analytics.brandsafety.BrandSafetyUtils; import com.safedk.android.analytics.brandsafety.creatives.AdNetworkConfiguration; import com.safedk.android.analytics.brandsafety.creatives.CreativeInfoManager; import com.safedk.android.utils.Logger; import com.safedk.android.utils.j; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Map; import org.json.JSONException; import org.json.JSONObject; public class SafeDKWebAppInterface { public static final String a = "SafeDKWebAppInterface"; public static final String b = "status"; public static final String c = "playing"; public static final String d = "paused"; public static final String e = "sdk_id"; public static final String f = "javascript:"; public static final String g = "(function(){var isMainFrame=function(){return window.location===window.parent.location};var log=function(message){try{window.webkit.messageHandlers.safedkDebug.postMessage(message)}catch(error){}};var sdkId=\"{{SDK_ID}}\";var endCardDetected=false;var isElementHidden=function(element){try{while(element){if(getComputedStyle(element).display==\"none\")return true;element=element.parentElement}}catch(error){window.webkit.messageHandlers.safedkVideoExc.postMessage(error.message+\"\\n\"+error.stack)}return false};var isElementInEventHidden=function(event){return isElementHidden(event.srcElement)};var getVideoPath=function(event){try{var videoElement=event.srcElement;if(videoElement.tagName!=\"VIDEO\")return null;var path=videoElement.src;if(!path){var sourceNodes=videoElement.getElementsByTagName(\"SOURCE\");for(var sourceNode of sourceNodes){if(sourceNode.src){path=sourceNode.src;break}}}if(path){if(path.length>=200){path=path.substring(0,199)}}return path}catch(error){window.webkit.messageHandlers.safedkVideoExc.postMessage(error.message+\"\\n\"+error.stack)}return null};var notifyPlay=function(event){if(!endCardDetected){if(isElementInEventHidden(event))return;event.srcElement.safedkVideoPlaying=true;var message={status:\"playing\",sdk_id:sdkId};var src=getVideoPath(event);if(src)message[\"src\"]=src;log(\"Notifying client that video is playing for sdkId: \"+sdkId+\", video ID: \"+event.srcElement.id);window.webkit.messageHandlers.safedkVideo.postMessage(JSON.stringify(message))}};var notifyPause=function(event){if(!endCardDetected){event.srcElement.safedkVideoPlaying=false;var message={status:\"paused\",sdk_id:sdkId};var src=getVideoPath(event);if(src)message[\"src\"]=src;log(\"Notifying client that video is paused for sdkId: \"+sdkId+\", video ID: \"+event.srcElement.id);window.webkit.messageHandlers.safedkVideo.postMessage(JSON.stringify(message))}};var notifyEndCard=function(){if(!endCardDetected){endCardDetected=true;log(\"Notifying client that end-card detected for sdkId: \"+sdkId);var message={status:\"end-card\",sdk_id:sdkId};window.webkit.messageHandlers.safedkVideo.postMessage(JSON.stringify(message))}};var addVideoListeners=function(doc){try{if(doc.nodeName==\"#text\")return;var videoElements=doc.getElementsByTagName(\"VIDEO\");if(videoElements.length==0){if(doc.tagName&&doc.tagName==\"VIDEO\"){videoElements=[doc]}}for(i=0;i<videoElements.length;i++){var videoElement=videoElements[i];if(videoElement.safedkVideoListeners!=true){log(\"Found VIDEO tag, adding event listeners. sdkId: \"+sdkId+\", video ID: \"+videoElement.id);videoElement.safedkVideoListeners=true;videoElement.addEventListener(\"play\",notifyPlay);videoElement.addEventListener(\"pause\",notifyPause)}}}catch(error){}};var addEndCardObserver=function(){try{var endCardElement=document.getElementById(\"al_endCardDiv\");if(endCardElement){var computedStyle=getComputedStyle(endCardElement);if(computedStyle&&computedStyle.display==\"flex\"){log(\"Found visible al_endCardDiv tag. sdkId: \"+sdkId);notifyEndCard()}else{if(endCardElement.safedkEndCardObserver!=true){endCardElement.safedkEndCardObserver=true;log(\"Found al_endCardDiv tag, adding end-card observer. sdkId: \"+sdkId);try{var MutationObserver=window.WebKitMutationObserver||window.MutationObserver;var observer=new MutationObserver(function(mutations){mutations.forEach(function(mutation){switch(mutation.type){case\"attributes\":computedStyle=getComputedStyle(mutation.target);if(computedStyle&&computedStyle.display==\"flex\"){notifyEndCard()}break}})});var config={attributes:true,attributeOldValue:true,attributeFilter:[\"style\"]};observer.observe(endCardElement,config)}catch(error){window.webkit.messageHandlers.safedkVideoExc.postMessage(error.message+\"\\n\"+error.stack)}}}}}catch(error){window.webkit.messageHandlers.safedkVideoExc.postMessage(error.message+\"\\n\"+error.stack)}};log(\"Initializing video observer\");addVideoListeners(document);if(sdkId.startsWith(\"com.applovin\")){addEndCardObserver()}try{var MutationObserver=window.WebKitMutationObserver||window.MutationObserver;var observer=new MutationObserver(function(mutations){mutations.forEach(function(mutation){for(var node of mutation.addedNodes){log(\"Add video listeners for added elements: \"+node);addVideoListeners(node)}for(var node of mutation.removedNodes){if(node.tagName){var removedVideoElements=node.getElementsByTagName(\"VIDEO\");for(var removedVideoElement of removedVideoElements){if(removedVideoElement.safedkVideoPlaying){log(\"VIDEO tag removed. Calling notifyPause\");var event={srcElement:removedVideoElement};notifyPause(event)}}}}if(sdkId.startsWith(\"com.applovin\")){addEndCardObserver()}})});var config={childList:true,subtree:true};observer.observe(document,config)}catch(error){window.webkit.messageHandlers.safedkVideoExc.postMessage(error.message+\"\\n\"+error.stack)}})();\n"; public static final String h = "(function(){var webviewAddress=\"{{webviewAddress}}\";var sdkPackage=\"{{sdkPackage}}\";var log=function(message){try{window.webkit.messageHandlers.safedkDebug.postMessage(\"get_text \"+sdkPackage+\" \"+webviewAddress+\" : \"+message)}catch(error){}};var textContentUnder=function(element){var n;var s=new Set;try{if(element){var walk=document.createTreeWalker(element,NodeFilter.SHOW_TEXT,null,false);while(n=walk.nextNode()){var parent=n.parentElement;if(!parent)continue;if(parent.nodeType!=1)continue;if(parent.tagName==\"SCRIPT\"||parent.tagName==\"NOSCRIPT\"||parent.tagName==\"STYLE\"||parent.tagName==\"IFRAME\")continue;if(isHidden(parent))continue;var text=n.textContent.trim();if(text==\"\")continue;log(\"textContentUnder added \"+text);s.add(text)}}}catch(error){log(\"error : \"+error)}return s};var isHidden=function(element){try{while(element){if(getComputedStyle(element).display==\"none\")return true;element=element.parentElement}}catch(error){console.log(\"error : \"+error)}return false};var collectText=function(element){var textArray=textContentUnder(document.body);var text=Array.from(textArray).join(\"---\");log(\"sdkPackage = \"+sdkPackage+\", address = \"+webviewAddress+\", text = \"+text);try{window.webkit.messageHandlers.safedkDebug.setContent(sdkPackage,webviewAddress,text)}catch(error){log(\"collectText error : \"+error)}};var i=0;var interval=1e3;setInterval(function(){if(i<10){log(\"debug setInterval i = \"+i);i++;collectText()}},interval)})();\n"; private static final String k = "privacy"; private static final String l = "end_of_video"; private static final String m = "extract_text"; Context j; private static final CharSequence n = "https://webview.unityads.unity3d.com/webview/"; private static final CharSequence o = "UnityAdsWebApp.html"; public static final Map<String, WeakReference<WebView>> i = new HashMap(); public SafeDKWebAppInterface(Context c2) { this.j = c2; } @JavascriptInterface public void postMessage(String msg) { String str; boolean z = true; Logger.d(a, "postMessage : msg = " + msg); try { JSONObject jSONObject = new JSONObject(msg); if (!jSONObject.has("status")) { z = false; } else if (jSONObject.get("status").equals(c)) { z = false; } if (!jSONObject.has(e)) { str = null; } else { str = jSONObject.getString(e); } Logger.d(a, "postMessage : status = " + z + ", sdk_id = " + str + ", src = " + (jSONObject.has("src") ? jSONObject.get("src") : "NA")); if (str != null) { String[] split = str.split("~"); CreativeInfoManager.a(split[0], split[1], z); } } catch (JSONException e2) { Logger.d(a, "Received msg is not a JSON object : " + msg); } } @JavascriptInterface public void logMessage(String msg) { Logger.d(a, "logMessage msg = " + msg); } @JavascriptInterface public void requestNoSampling(String sdkPackageName, String address, int height, int width) { Logger.d(a, "requestNoSampling : address = " + address + ", height = " + height + " , width = " + width); if (j.a(width, height)) { Logger.d(a, "requestNoSampling calling banner requestNoSampling, : address = " + address); CreativeInfoManager.a(BrandSafetyUtils.AdType.BANNER, address); } else if (j.b(width, height)) { Logger.d(a, "requestNoSampling calling MREC requestNoSampling, : address = " + address); CreativeInfoManager.a(BrandSafetyUtils.AdType.MREC, address); } else if (b.getInstance().isInterstitialActivity(b.getInstance().getForegroundActivity())) { Logger.d(a, "requestNoSampling calling interstitial requestNoSampling, : address = " + address); CreativeInfoManager.b(sdkPackageName, address); } else { Logger.d(a, "requestNoSampling WebView is non a banner nor an interstitial, probably MREC, : address = " + address); } } @JavascriptInterface public void setContent(String packageName, String webviewAddress, String texts) { WeakReference<WebView> weakReference; try { if (com.safedk.android.utils.a.a(packageName)) { if (texts != null && texts.trim().length() > 0) { Logger.d(a, "setContent packageName = " + packageName + ", webviewAddress = " + webviewAddress + ", text = " + texts); if (i.containsKey(webviewAddress) && (weakReference = i.get(webviewAddress)) != null && weakReference.get() != null) { for (String str : texts.split("---")) { if (str != null && str.trim().length() > 0) { com.safedk.android.analytics.brandsafety.creatives.e.a(packageName, weakReference.get(), "text:" + str, null); } } return; } return; } Logger.d(a, "setContent WebView address " + webviewAddress + " text is empty"); } } catch (Throwable th) { Logger.d(a, "setContent exception : " + th.getMessage() + ", webviewAddress = " + webviewAddress, th); } } public static void a(String str, WebView webView, String str2) { String a2 = BrandSafetyUtils.a(webView); SafeDK safeDK = SafeDK.getInstance(); Logger.d(a, "addJScript started sdkPackage=" + str + ", webView=" + a2 + " ,url=" + str2 + " , isMaxInit=" + SafeDK.S()); if (str2 == null) { Logger.d(a, "addJScript loaded url is empty, skipping."); return; } if ((SafeDK.S() && safeDK != null && !safeDK.f()) || str2.contains(n) || str2.contains(o)) { if (str2.startsWith(f)) { Logger.d(a, "addJScript loaded data is javascript, ignoring. url : " + str2); return; } if (SafeDK.I() && Build.VERSION.SDK_INT >= 19) { WebView.setWebContentsDebuggingEnabled(true); } webView.addJavascriptInterface(new SafeDKWebAppInterface(webView.getContext()), a); Logger.d(a, "addJScript javascript interface added, WebView address is " + a2); if (SafeDK.I() && Build.VERSION.SDK_INT >= 19) { Logger.d(a, "addJScript testing javascript call. WebView address is " + a2); webView.evaluateJavascript("javascript:console.log('adding js interface');", null); webView.evaluateJavascript("javascript:console.log(document.getElementByName);", null); webView.evaluateJavascript("javascript:window.SafeDKWebAppInterface.logMessage('adding js interface');", null); } b(str, webView, str2); } } public static String a(String str, String str2, String str3) { return f + str3.replace("window.webkit.", "window.").replace("messageHandlers.safedkNoSamplingExc.postMessage", "SafeDKWebAppInterface.logMessage").replace("messageHandlers.safedkNoSampling.postMessage", "SafeDKWebAppInterface.requestNoSampling").replace("messageHandlers.safedkDebug.postMessage", "SafeDKWebAppInterface.logMessage").replace("{{SDK_ID}}", str).replace("{{ADDRESS}}", str2); } public static String a(String str, String str2) { return f + g.replace("window.webkit.", "window.").replace("messageHandlers.safedkDebug.postMessage", "SafeDKWebAppInterface.logMessage").replace("messageHandlers.safedkVideoExc.postMessage", "SafeDKWebAppInterface.logMessage").replace("messageHandlers.safedkNoSampling.postMessage", "SafeDKWebAppInterface.logMessage").replace("messageHandlers.safedkVideo", a).replace("{{SDK_ID}}", str + "~" + str2); } public static String b(String str, String str2) { Logger.d(a, "getting js html extr script for webviewAddress " + str2); return f + h.replace("{{webviewAddress}}", str2).replace("{{sdkPackage}}", str).replace("window.webkit.", "window.").replace("messageHandlers.safedkDebug.postMessage", "SafeDKWebAppInterface.logMessage").replace("messageHandlers.safedkDebug.setContent", "SafeDKWebAppInterface.setContent"); } public static void b(final String str, final WebView webView, final String str2) { final String a2 = BrandSafetyUtils.a(webView); SafeDK safeDK = SafeDK.getInstance(); if (SafeDK.S() && safeDK != null && !SafeDK.getInstance().f()) { if (str2 == null || str2.equalsIgnoreCase("about:blank") || str2.trim().length() == 0) { Logger.d(a, "url is blank, skipping scripts injection. sdkPackage = " + str + ", webView = " + webView + ", url = " + str2); return; } final HashMap hashMap = new HashMap(); Logger.d(a, "atchJsScript sdk: " + str + ", address: " + a2 + " resource: " + str2); com.safedk.android.analytics.brandsafety.creatives.a g2 = CreativeInfoManager.g(str); if (g2 == null) { Logger.d(a, "atchJsScript configBundle is empty, existing"); return; } if (g2 != null) { Logger.d(a, "atchJsScript sdk " + str + " items: js privacy : " + g2.a(AdNetworkConfiguration.SUPPORTS_JAVASCRIPT_BASED_PRIVACY_BUTTON_CLICK_DETECTION, false) + ", js video : " + g2.a(AdNetworkConfiguration.SUPPORTS_JAVASCRIPT_BASED_VIDEO_STATE_DETECTION, false)); } else { Logger.d(a, "atchJsScript sdk " + str + " config bundle is empty"); } if (g2.a(AdNetworkConfiguration.SUPPORTS_JAVASCRIPT_BASED_PRIVACY_BUTTON_CLICK_DETECTION, false)) { String a3 = g2.a(AdNetworkConfiguration.JS_PRIVACY_BUTTON_CLICK_DETECTION_SCRIPT, (String) null); if (a3 != null && a3.length() > 0) { hashMap.put(k, a(str, a2, a3)); Logger.d(a, "attachJsScript added " + str + " privacy button click detection script to list."); } else { Logger.d(a, "attachJsScript privacy button click detection script is empty, skipping."); } } if (g2.b(AdNetworkConfiguration.SUPPORTS_JAVASCRIPT_BASED_VIDEO_STATE_DETECTION)) { hashMap.put(l, a(str, a2)); Logger.d(a, "atchJsScript added " + str + " video state detection script to list."); } else { Logger.d(a, "atchJsScript no need to add video state detection script. WebView : " + a2); } if (g2.b(AdNetworkConfiguration.SUPPORTS_BANNER_IMPRESSION_TRACKING)) { if (!b.getInstance().isInterstitialActivity(webView.getContext())) { synchronized (i) { i.put(a2, new WeakReference<>(webView)); } hashMap.put(m, b(str, a2)); Logger.d(a, "atchJsScript added " + str + " text extraction script to list."); } else { Logger.d(a, "atchJsScript WebView is in an interstitial, skipping text extraction script. sdk: " + str + ", context = " + webView.getContext()); } } else { Logger.d(a, "atchJsScript no need to add text extraction script. WebView : " + a2); } webView.post(new Runnable() { @Override public void run() { if (Build.VERSION.SDK_INT >= 19) { if (webView != null) { for (String str3 : hashMap.keySet()) { if (hashMap.get(str3) != null && ((String) hashMap.get(str3)).length() > 0) { String str4 = (String) hashMap.get(str3); j.b(SafeDKWebAppInterface.a, "Injecting script for " + str + " WebView : " + a2 + ", url = " + str2 + ", script : " + str3); try { webView.evaluateJavascript(str4, null); } catch (Throwable th) { Logger.d(SafeDKWebAppInterface.a, "atchJsScript Exception injecting text extraction script : " + th.getMessage(), th); } } } } hashMap.clear(); return; } for (String str5 : hashMap.keySet()) { String str6 = (String) hashMap.get(str5); if (str6 != null && str6.length() > 0 && webView != null) { Logger.d(SafeDKWebAppInterface.a, "Injecting script for " + str + " WebView : " + a2 + ", url = " + str2 + ", script : " + str5); try { webView.loadUrl(str6, null); } catch (Throwable th2) { Logger.d(SafeDKWebAppInterface.a, "Exception injecting text extraction script : " + th2.getMessage(), th2); } } } } }); } } public static void a(String str) { synchronized (i) { i.remove(str); } Logger.d(a, "WebView address removed : " + str); } }