4646import android .view .ViewGroup ;
4747import android .webkit .PermissionRequest ;
4848import android .webkit .WebChromeClient ;
49+ import android .webkit .WebResourceRequest ;
4950import android .webkit .WebSettings ;
5051import android .webkit .WebView ;
52+ import android .webkit .WebViewClient ;
5153import android .widget .ProgressBar ;
5254
5355import androidx .activity .result .ActivityResultLauncher ;
8789
8890import static com .microsoft .identity .common .java .AuthenticationConstants .OAuth2 .UTID ;
8991
92+ import com .microsoft .identity .common .java .opentelemetry .OTelUtility ;
93+ import com .microsoft .identity .common .java .opentelemetry .SpanName ;
9094
95+ import io .opentelemetry .api .trace .Span ;
9196import io .opentelemetry .api .trace .SpanContext ;
97+ import io .opentelemetry .api .trace .StatusCode ;
98+ import io .opentelemetry .context .Scope ;
9299
93100/**
94101 * Authorization fragment with embedded webview.
@@ -352,6 +359,13 @@ public boolean onTouch(final View view, final MotionEvent event) {
352359 mWebView .getSettings ().setUseWideViewPort (true );
353360 mWebView .getSettings ().setBuiltInZoomControls (webViewZoomControlsEnabled );
354361 mWebView .getSettings ().setSupportZoom (webViewZoomEnabled );
362+
363+ // Enable multiple windows so that target="_blank" links trigger onCreateWindow
364+ // instead of being silently dropped by the WebView - controlled by flight.
365+ final boolean multipleWindowsEnabled = CommonFlightsManager .INSTANCE .getFlightsProvider ()
366+ .isFlightEnabled (CommonFlight .ENABLE_WEBVIEW_MULTIPLE_WINDOWS );
367+ mWebView .getSettings ().setSupportMultipleWindows (multipleWindowsEnabled );
368+
355369 mWebView .setVisibility (View .INVISIBLE );
356370 mWebView .setWebViewClient (webViewClient );
357371 mWebView .setWebChromeClient (new WebChromeClient () {
@@ -376,6 +390,46 @@ public Bitmap getDefaultVideoPoster() {
376390 // We will return a 10x10 empty image, instead of the default grey playback image. #2424
377391 return Bitmap .createBitmap (10 , 10 , Bitmap .Config .ARGB_8888 );
378392 }
393+
394+ @ Override
395+ public boolean onCreateWindow (final WebView view , boolean isDialog ,
396+ boolean isUserGesture , final android .os .Message resultMsg ) {
397+ if (!multipleWindowsEnabled ) {
398+ // Flight is off; should not reach here, but guard anyway.
399+ return false ;
400+ }
401+ // Handles target="_blank" links by opening them in the device's default browser
402+ // instead of silently dropping the navigation.
403+ final SpanContext parentSpanContext = requireActivity () instanceof AuthorizationActivity
404+ ? ((AuthorizationActivity ) requireActivity ()).getSpanContext () : null ;
405+ final Span span = OTelUtility .createSpanFromParent (
406+ SpanName .WebViewTargetBlankNavigation .name (), parentSpanContext );
407+ try (final Scope scope = span .makeCurrent ()) {
408+ Logger .info (methodTag , "onCreateWindow: intercepting target=_blank navigation." );
409+ final WebView tempWebView = new WebView (view .getContext ());
410+ tempWebView .setWebViewClient (new WebViewClient () {
411+ @ Override
412+ public boolean shouldOverrideUrlLoading (WebView v , WebResourceRequest request ) {
413+ final String url = request .getUrl ().toString ();
414+ Logger .info (methodTag , "onCreateWindow: opening target=_blank URL in external browser." );
415+ span .setAttribute ("target_blank_url" , url );
416+ final Intent browserIntent = new Intent (Intent .ACTION_VIEW , Uri .parse (url ));
417+ view .getContext ().startActivity (browserIntent );
418+ return true ;
419+ }
420+ });
421+ final WebView .WebViewTransport transport = (WebView .WebViewTransport ) resultMsg .obj ;
422+ transport .setWebView (tempWebView );
423+ resultMsg .sendToTarget ();
424+ span .setStatus (StatusCode .OK );
425+ } catch (final Exception e ) {
426+ Logger .error (methodTag , "Error handling target=_blank navigation." , e );
427+ span .setStatus (StatusCode .ERROR , e .getMessage ());
428+ } finally {
429+ span .end ();
430+ }
431+ return true ;
432+ }
379433 });
380434 setupPasskeyWebListener (mWebView , webViewClient );
381435 }
0 commit comments