How to get RenderFrameHost for ResourceRequestInfo?

86 views
Skip to first unread message

Anton Smirnov

unread,
May 16, 2018, 4:52:30 AM5/16/18
to Chromium-dev
Hey, guys.

I'm working on Chromium fork for Android that filters some requests.
For this in `chrome_network_delegate.cc` for some resources i return `net::ERR_BLOCKED_BY_ADMINISTRATOR`.
It works but now i need to know iframe and all parent iframes URLs to define if i need to filter  request or not.

So i try to get RenderFrameHost instance for ResourceRequestInfo

`chrome_network_delegate.cc`:
```
...
int ChromeNetworkDelegate::OnBeforeStartTransaction(
...

      const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
      int render_process_id, render_frame_id;
      if (info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) {
        LOG(WARNING) << "Adblock: got render_process_id=" << render_process_id
                     << ", render_frame_id=" << render_frame_id;
        content::RenderFrameHost* frameHost = content::RenderFrameHost::FromID(render_process_id, render_frame_id); //
        LOG(WARNING) << "Filtering: relates to frame " << frameHost->GetFrameName();
...
```

The actual problem is that `content::RenderFrameHost::FromID` should happen on UI thread and it works in some background thread:
```
```

What can i do?

I think i could send to UI thread using tasks. But then i have to wait here and in general it does not sound good to do some work in UI thread.
Any specific reason to run `FromID` on UI thread?

Any thoughts are higly appreciated.



Message has been deleted

Anton Smirnov

unread,
May 16, 2018, 8:48:30 AM5/16/18
to Chromium-dev
I've also tried the following:

      int frame_tree_node_id = info->GetFrameTreeNodeId();
      content::FrameTreeNode* frame_tree_node = content::FrameTreeNode::GloballyFindByID(frame_tree_node_id);

      if (frame_tree_node) {
        LOG(WARNING) << "Filtering: relates to frame " << frame_tree_node->current_url();
      } else {
        LOG(ERROR) << "Filtering: failed to find FrameTreeNode";
      }

But unfortunately it fails too because it have to be called on UI thread too:

05-16 17:44:58.317 300-300 I/DEBUG: Abort message: '[FATAL:frame_tree_node.cc(124)] Check failed: ::content::BrowserThread::CurrentlyOn(BrowserThread::UI). Must be called on Chrome_UIThread; actually called on Chrome_IOThread.
                                    #00 0x9f3f67dd /data/app/org.chromium.chrome-1/lib/arm/libbase.cr.so+0x000a87dd
                                    #01 0x994e30fb /data/app/org.chromium.chrome-1/lib/arm/libcontent.cr.so+0x008f10fb
                                    #02 0x9794171b /data/app/org.chromium.chrome-1/lib/arm/libchrome.cr.so+0x0049571b
                                    #03 0x9e44467f /data/app/org.chromium.chrome-1/lib/arm/libnet.cr.so+0x001bf
05-16 17:44:58.317 300-300 I/DEBUG:     r0 00000000  r1 000059f8  r2 00000006  r3 00000000
05-16 17:44:58.317 300-300 I/DEBUG:     r4 94b01db8  r5 00000006  r6 0000000b  r7 0000010c
05-16 17:44:58.317 300-300 I/DEBUG:     r8 9f49a0b8  r9 9f49ade0  sl 94b008b4  fp 94b008b8
05-16 17:44:58.317 300-300 I/DEBUG:     ip 000059f8  sp 94b003d8  lr b6efcfd5  pc b6f204b0  cpsr 60070010
05-16 17:44:58.317 300-300 I/DEBUG: backtrace:
05-16 17:44:58.317 300-300 I/DEBUG:     #00 pc 000374b0  /system/lib/libc.so (tgkill+12)
05-16 17:44:58.317 300-300 I/DEBUG:     #01 pc 00013fd1  /system/lib/libc.so (pthread_kill+52)
05-16 17:44:58.317 300-300 I/DEBUG:     #02 pc 00014bef  /system/lib/libc.so (raise+10)
05-16 17:44:58.317 300-300 I/DEBUG:     #03 pc 00011531  /system/lib/libc.so (__libc_android_abort+36)
05-16 17:44:58.317 300-300 I/DEBUG:     #04 pc 0000fcbc  /system/lib/libc.so (abort+4)
05-16 17:44:58.317 300-300 I/DEBUG:     #05 pc 00097105  /data/app/org.chromium.chrome-1/lib/arm/libbase.cr.so(base::debug::BreakDebugger()+20)
05-16 17:44:58.317 300-300 I/DEBUG:     #06 pc 000a89f3  /data/app/org.chromium.chrome-1/lib/arm/libbase.cr.so (logging::LogMessage::~LogMessage()+658)
05-16 17:44:58.317 300-300 I/DEBUG:     #07 pc 008f10f9  /data/app/org.chromium.chrome-1/lib/arm/libcontent.cr.so(content::FrameTreeNode::GloballyFindByID(int)+68)
05-16 17:44:58.317 300-300 I/DEBUG:     #08 pc 00495719  /data/app/org.chromium.chrome-1/lib/arm/libchrome.cr.so

Alex Clarke

unread,
May 16, 2018, 9:04:45 AM5/16/18
to Anton Smirnov, Chromium-dev
Perhaps take a look at DevToolsURLRequestInterceptor for inspiration. Rather than using RenderFrameHost it uses FrameTreeNode::devtools_frame_token which it gets from the result returned by DevToolsURLRequestInterceptor::TargetInfoForRequestInfo.

--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev+unsubscribe@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-dev/397032a2-2953-4dd0-9ac6-29f7cba94d7f%40chromium.org.

Anton Smirnov

unread,
May 16, 2018, 2:20:29 PM5/16/18
to Chromium-dev, d...@antonsmirnov.name
Hi, Alex.
Thanks for pointing a direction.

However if i'm right it returns TargetInfo:

I can't figure out how it can be used to get resource iframe (FrameTreeNode) on background thread.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.
Message has been deleted

Anton Smirnov

unread,
May 17, 2018, 8:25:15 AM5/17/18
to Chromium-dev
I've found to do what i need in the following:

void findAndOutputRenderFrameHost(std::string url, int render_process_id, int render_frame_id) {
  content::RenderFrameHost* frameHost = content::RenderFrameHost::FromID(render_process_id, render_frame_id);
  if (frameHost) {
    content::FrameTreeNode* node = content::FrameTreeNode::GloballyFindByID(frameHost->GetFrameTreeNodeId());
    if (node) {
      LOG(WARNING) << "Filtering: " << url
                   << " relates to frame " << frameHost->GetFrameName()
                   << " with url " << node->current_url().spec()
                   << " and parent frame url " << (node->parent()
                      ? node->parent()->current_url().spec()
                      : "(no parent)");
    } else {
      LOG(ERROR) << "Filtering: failed to get FrameTreeNode";
    }
  } else {
    LOG(ERROR) << "Filtering: failed to get RenderFrameHost";
  }
}

...

int ChromeNetworkDelegate::OnBeforeStartTransaction(

...

    const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);

    LOG(WARNING) << "Filtering: casted to FilteringPlus::FilterEnginePtr, "
                 << "use_count = " << filterEngine.use_count();

    content::ResourceType resource_type;
    if (info) {
      resource_type = info->GetResourceType();
      bool isResourceTypeImage = (resource_type == content::RESOURCE_TYPE_IMAGE);
      LOG(WARNING) << "Filtering: resource type of "
                   << url << " is " << info->GetResourceType()
                   << " (isImage = " << (isResourceTypeImage ? "true" : "false") << ")"
                   << " frameTreeNodeId = " << info->GetFrameTreeNodeId();

      int render_process_id, render_frame_id;
      if (info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) {
        LOG(WARNING) << "Filtering: got render_process_id=" << render_process_id
                     << ", render_frame_id=" << render_frame_id;

        // schedule to run on UI thread
        content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI)
          ->PostTask(FROM_HERE, base::BindOnce(&findAndOutputRenderFrameHost, url, render_process_id, render_frame_id));
      }
      
    } else {
      LOG(WARNING) << "Filtering: No resourceRequestInfo";
    }

Is there any opportunity to call findAndOutputRenderFrameHost not on UI thread, but where it's posted to UI thread (current thread)?
Whats fundamental reason of calling content::RenderFrameHost::FromID() and content::FrameTreeNode::GloballyFindByID in UI thread only?
Any chance to workaround it - post to UI thread and wait here until response is received?

On Wednesday, May 16, 2018 at 1:52:30 PM UTC+5, Anton Smirnov wrote:
Hey, guys.

I'm working on Chromium fork for Android that filters some requests.
For this in `chrome_network_delegate.cc` for some resources i return `net::ERR_BLOCKED_BY_ADMINISTRATOR`.
It works but now i need to know iframe and all parent iframes URLs to define if i need to filter  request or not.

So i try to get RenderFrameHost instance for ResourceRequestInfo

`chrome_network_delegate.cc`:
```
...
int ChromeNetworkDelegate::OnBeforeStartTransaction(
...

      const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
      int render_process_id, render_frame_id;
      if (info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) {
        LOG(WARNING) << "Filtering: got render_process_id=" << render_process_id
                     << ", render_frame_id=" << render_frame_id;
        content::RenderFrameHost* frameHost = content::RenderFrameHost::FromID(render_process_id, render_frame_id); //
        LOG(WARNING) << "Filtering: relates to frame " << frameHost->GetFrameName();

Anton Smirnov

unread,
May 17, 2018, 3:33:34 PM5/17/18
to Chromium-dev
It looks like network thread does not allow blocking (waiting with base::ConditionVariable) as
i'm getting assert failure. So i wonder how can i block the thread until i find RenderFrameHost in UI thread..


On Wednesday, May 16, 2018 at 1:52:30 PM UTC+5, Anton Smirnov wrote:
Reply all
Reply to author
Forward
0 new messages