1414import com .codename1 .ui .Form ;
1515import com .codename1 .ui .Image ;
1616import com .codename1 .ui .Label ;
17+ import com .codename1 .ui .Toolbar ;
1718import com .codename1 .ui .layouts .BorderLayout ;
1819import com .codename1 .ui .layouts .GridLayout ;
1920import com .codename1 .ui .plaf .Style ;
2021import com .codename1 .ui .util .ImageIO ;
2122import com .codename1 .ui .util .UITimer ;
2223import java .io .IOException ;
2324import java .io .OutputStream ;
25+ import java .lang .reflect .Field ;
26+ import java .lang .reflect .Method ;
2427
2528public class CefFfmpegSmoke extends Lifecycle {
2629 private static final String SCREENSHOT_NAME = "cef-ffmpeg-smoke.png" ;
2730 private static final String STATUS_NAME = "cef-ffmpeg-smoke-status.txt" ;
28- private static final int CAPTURE_DELAY_MS = 1500 ;
31+ private static final int CAPTURE_DELAY_MS = 3000 ;
2932 private static final int FALLBACK_TIMEOUT_MS = 12000 ;
3033
3134 private Form current ;
3235 private Media media ;
3336 private boolean browserLoaded ;
37+ private boolean browserJsVerified ;
38+ private String browserColor = "" ;
39+ private String browserReadyState = "" ;
40+ private boolean cefLoaded ;
41+ private String displayImplementationClass = "" ;
42+ private String browserPeerClass = "" ;
43+ private boolean browserPeerReady ;
3444 private boolean captureScheduled ;
3545 private boolean captured ;
3646
3747 @ Override
3848 public void init (Object context ) {
39- super .init (context );
49+ CN .updateNetworkThreadCount (2 );
50+ Toolbar .setGlobalToolbar (true );
4051 Display .getInstance ().setProperty ("BrowserComponent.useCEF" , "true" );
4152 }
4253
@@ -70,8 +81,7 @@ public void start() {
7081 browser .setPreferredW (320 );
7182 browser .setPreferredH (240 );
7283 browser .addWebEventListener (BrowserComponent .onLoad , evt -> {
73- browserLoaded = true ;
74- maybeScheduleCapture (form );
84+ probeBrowser (browser , form );
7585 });
7686 browser .setPage ("<html><body style='margin:0;background:#00ff00;'></body></html>" , null );
7787
@@ -95,6 +105,17 @@ public void start() {
95105 current = form ;
96106 form .show ();
97107
108+ final UITimer [] browserProbe = new UITimer [1 ];
109+ browserProbe [0 ] = UITimer .timer (500 , true , form , () -> {
110+ if (captured ) {
111+ browserProbe [0 ].cancel ();
112+ return ;
113+ }
114+ if (probeBrowser (browser , form )) {
115+ browserProbe [0 ].cancel ();
116+ }
117+ });
118+
98119 UITimer .timer (300 , false , form , () -> {
99120 try {
100121 if (media != null ) {
@@ -134,11 +155,11 @@ public void destroy() {
134155 }
135156
136157 private void maybeScheduleCapture (Form form ) {
137- if (captureScheduled || captured || !browserLoaded || media == null ) {
158+ if (captureScheduled || captured || !browserPeerReady || media == null ) {
138159 return ;
139160 }
140161 captureScheduled = true ;
141- UITimer .timer (CAPTURE_DELAY_MS , false , form , () -> captureAndExit ("browser-loaded " ));
162+ UITimer .timer (CAPTURE_DELAY_MS , false , form , () -> captureAndExit ("browser-peer-ready " ));
142163 }
143164
144165 private void captureAndExit (String reason ) {
@@ -147,7 +168,14 @@ private void captureAndExit(String reason) {
147168 }
148169 captured = true ;
149170 writeStatus ("captureReason=" + reason + "\n " +
171+ "cefLoaded=" + cefLoaded + "\n " +
172+ "displayImplementationClass=" + displayImplementationClass + "\n " +
173+ "browserPeerClass=" + browserPeerClass + "\n " +
174+ "browserPeerReady=" + browserPeerReady + "\n " +
150175 "browserLoaded=" + browserLoaded + "\n " +
176+ "browserJsVerified=" + browserJsVerified + "\n " +
177+ "browserReadyState=" + browserReadyState + "\n " +
178+ "browserColor=" + browserColor + "\n " +
151179 "mediaImplementation=" + System .getProperty ("cn1.javase.mediaImplementation" , "" ) + "\n " +
152180 "browserImplementation=" + System .getProperty ("cn1.javase.implementation" , "" ) + "\n " );
153181 Display .getInstance ().screenshot (img -> {
@@ -197,6 +225,68 @@ private void writeStatus(String text) {
197225 }
198226 }
199227
228+ private boolean probeBrowser (BrowserComponent browser , Form form ) {
229+ inspectBrowserBackend (browser );
230+ try {
231+ browserReadyState = browser .executeAndReturnString ("document.readyState" );
232+ browserColor = browser .executeAndReturnString ("window.getComputedStyle(document.body).backgroundColor" );
233+ browserLoaded = browserReadyState != null && browserReadyState .length () > 0 ;
234+ browserJsVerified = browserColor != null && browserColor .indexOf ("0, 255, 0" ) >= 0 ;
235+ if (browserLoaded || browserPeerReady ) {
236+ maybeScheduleCapture (form );
237+ }
238+ return browserLoaded ;
239+ } catch (RuntimeException ex ) {
240+ browserReadyState = "error:" + ex .getMessage ();
241+ browserColor = "" ;
242+ browserJsVerified = false ;
243+ if (browserPeerReady ) {
244+ maybeScheduleCapture (form );
245+ }
246+ return false ;
247+ }
248+ }
249+
250+ private void inspectBrowserBackend (BrowserComponent browser ) {
251+ cefLoaded = isCefLoaded ();
252+ displayImplementationClass = getDisplayImplementationClass ();
253+ browserPeerClass = getBrowserPeerClass (browser );
254+ browserPeerReady = browserPeerClass .length () > 0 ;
255+ }
256+
257+ private boolean isCefLoaded () {
258+ try {
259+ Class <?> cls = Class .forName ("com.codename1.impl.javase.CN1Bootstrap" );
260+ Method m = cls .getMethod ("isCEFLoaded" );
261+ Object out = m .invoke (null );
262+ return Boolean .TRUE .equals (out );
263+ } catch (Throwable ex ) {
264+ return false ;
265+ }
266+ }
267+
268+ private String getDisplayImplementationClass () {
269+ try {
270+ Method m = Display .class .getDeclaredMethod ("getImplementation" );
271+ m .setAccessible (true );
272+ Object impl = m .invoke (Display .getInstance ());
273+ return impl == null ? "" : impl .getClass ().getName ();
274+ } catch (Throwable ex ) {
275+ return "error:" + ex .getClass ().getName ();
276+ }
277+ }
278+
279+ private String getBrowserPeerClass (BrowserComponent browser ) {
280+ try {
281+ Field f = BrowserComponent .class .getDeclaredField ("internal" );
282+ f .setAccessible (true );
283+ Object peer = f .get (browser );
284+ return peer == null ? "" : peer .getClass ().getName ();
285+ } catch (Throwable ex ) {
286+ return "error:" + ex .getClass ().getName ();
287+ }
288+ }
289+
200290 private String getAppHomePath () {
201291 return FileSystemStorage .getInstance ().getAppHomePath ();
202292 }
0 commit comments