GeckoViewContentBlocking.sys.mjs (3215B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { GeckoViewModule } from "resource://gre/modules/GeckoViewModule.sys.mjs"; 6 7 export class GeckoViewContentBlocking extends GeckoViewModule { 8 onEnable() { 9 const flags = Ci.nsIWebProgress.NOTIFY_CONTENT_BLOCKING; 10 this.progressFilter = Cc[ 11 "@mozilla.org/appshell/component/browser-status-filter;1" 12 ].createInstance(Ci.nsIWebProgress); 13 this.progressFilter.addProgressListener(this, flags); 14 this.browser.addProgressListener(this.progressFilter, flags); 15 16 this.registerListener(["ContentBlocking:RequestLog"]); 17 } 18 19 onDisable() { 20 if (this.progressFilter) { 21 this.progressFilter.removeProgressListener(this); 22 this.browser.removeProgressListener(this.progressFilter); 23 delete this.progressFilter; 24 } 25 26 this.unregisterListener(["ContentBlocking:RequestLog"]); 27 } 28 29 // Bundle event handler. 30 onEvent(aEvent, aData, aCallback) { 31 debug`onEvent: event=${aEvent}, data=${aData}`; 32 33 switch (aEvent) { 34 case "ContentBlocking:RequestLog": { 35 let bc = this.browser.browsingContext; 36 37 if (!bc) { 38 warn`Failed to export content blocking log.`; 39 break; 40 } 41 42 // Get the top-level browsingContext. The ContentBlockingLog is located 43 // in its current window global. 44 bc = bc.top; 45 46 const topWindowGlobal = bc.currentWindowGlobal; 47 48 if (!topWindowGlobal) { 49 warn`Failed to export content blocking log.`; 50 break; 51 } 52 53 const log = JSON.parse(topWindowGlobal.contentBlockingLog); 54 const res = Object.keys(log).map(key => { 55 const blockData = log[key].map(data => { 56 return { 57 category: data[0], 58 blocked: data[1], 59 count: data[2], 60 }; 61 }); 62 return { 63 origin: key, 64 blockData, 65 }; 66 }); 67 68 aCallback.onSuccess({ log: res }); 69 break; 70 } 71 } 72 } 73 74 onContentBlockingEvent(aWebProgress, aRequest, aEvent) { 75 debug`onContentBlockingEvent ${aEvent.toString(16)}`; 76 77 if (!(aRequest instanceof Ci.nsIClassifiedChannel)) { 78 return; 79 } 80 81 const channel = aRequest.QueryInterface(Ci.nsIChannel); 82 const uri = channel.URI && channel.URI.spec; 83 84 if (!uri) { 85 return; 86 } 87 88 const classChannel = aRequest.QueryInterface(Ci.nsIClassifiedChannel); 89 const blockedList = classChannel.matchedList || null; 90 let loadedLists = []; 91 92 if (aRequest instanceof Ci.nsIHttpChannel) { 93 loadedLists = classChannel.matchedTrackingLists || []; 94 } 95 96 debug`onContentBlockingEvent matchedList: ${blockedList}`; 97 debug`onContentBlockingEvent matchedTrackingLists: ${loadedLists}`; 98 99 const message = { 100 type: "GeckoView:ContentBlockingEvent", 101 uri, 102 category: aEvent, 103 blockedList, 104 loadedLists, 105 }; 106 107 this.eventDispatcher.sendRequest(message); 108 } 109 } 110 111 const { debug, warn } = GeckoViewContentBlocking.initLogging( 112 "GeckoViewContentBlocking" 113 );