blob: d2504dc85c65be7938ba84ef81f9b4cc36033b91 [file] [log] [blame]
Brian Silverman4e662aa2022-05-11 23:10:19 -07001// Copyright 2021 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use autocxx::prelude::*;
10mod render_frame_host;
11use render_frame_host::RenderFrameHostForWebContents;
12use render_frame_host::RenderFrameHostHandle;
13
14include_cpp! {
15 #include "fake-chromium-header.h"
16 safety!(unsafe) // unsafety policy; see docs
17 generate!("content::WebContents")
18 generate!("content::RenderFrameHost")
19 generate!("content::CreateParams")
20 generate!("SimulateRendererShutdown")
21 subclass!("content::WebContentsObserver",RenderFrameHostForWebContents)
22}
23
24use ffi::ToCppString;
25
26fn main() {
27 // Create some fake toy WebContents.
28 let create_params = ffi::content::CreateParams::new(&"silly-frame".into_cpp()).within_unique_ptr();
29 let mut frame = ffi::content::WebContents::Create(&create_params);
30
31 // This object is a memory-safe handle to a RenderFrameHost.
32 // On creation, we pass it the WebContents, such that it can register
33 // to be informed of the destruction of the RenderFrameHost.
34 // It also happens to store a reference to that WebContents,
35 // so the compiler will prove that this RenderFrameHostHandle
36 // can't outlive the WebContents. That's nice. But currently
37 // it stores an exclusive (a.k.a. mutable) reference, and we may
38 // well want to relax that in future.
39 // (This relates to https://github.com/google/autocxx/issues/622)
40 let mut rfh_handle = RenderFrameHostHandle::from_id(c_int(3), c_int(0), frame.pin_mut());
41
42 // We can directly call methods on the RFH.
43 // (If this were a 'const' method, the `.pin_mut()` wouldn't be necessary).
44 let frame_name = rfh_handle.pin_mut().GetFrameName();
45 println!("Frame name is {}", frame_name.to_str().unwrap());
46
47 {
48 // We can also borrow the RFH and use Rust's borrow checker to ensure
49 // no other code can do so. This also gives us a chance to explicitly
50 // handle the case where the RFH was already destroyed, in case
51 // we want to do something smarter than panicking.
52 let mut rfh_borrowed = rfh_handle
53 .try_borrow_mut()
54 .expect("Oh! The RFH was already destroyed!");
55 // Nobody else can borrow it during this time...
56 // let mut rfh_borrowed_again = rfh_handle.try_borrow_mut().unwrap();
57 // Gives compile-time error "second mutable borrow occurs here..."
58 let frame_name = rfh_borrowed.pin_mut().GetFrameName();
59 println!("Frame name is {}", frame_name.to_str().unwrap());
60 let frame_name = rfh_borrowed.pin_mut().GetFrameName();
61 println!("Frame name is {}", frame_name.to_str().unwrap());
62
63 // Supposing we end up calling some code deep in the Chrome C++
64 // stack which destroys the RFH whilst it's still borrowed.
65 // That will result in a runtime panic...
66 // ffi::SimulateRendererShutdown(c_int(0)); // would panic
67 }
68
69 // But let's assume we've now returned to the event loop.
70 // None of the previous borrows still exist. It's perfectly OK to now
71 // delete the RFH.
72 ffi::SimulateRendererShutdown(c_int(0));
73}