@capgo/capacitor-inappbrowser 8.15.2 → 8.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/CapgoInAppBrowserPlugin.java +13 -65
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/InAppBrowserPlugin.java +1 -2
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/SafeAreaInsetsSupport.java +7 -2
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/SystemUiChromeSupport.java +109 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +194 -195
- package/ios/Sources/InAppBrowserPlugin/InAppBrowserPlugin.swift +1 -1
- package/package.json +1 -1
|
@@ -20,7 +20,6 @@ import android.util.Log;
|
|
|
20
20
|
import android.webkit.CookieManager;
|
|
21
21
|
import android.webkit.PermissionRequest;
|
|
22
22
|
import android.webkit.WebView;
|
|
23
|
-
import androidx.activity.result.ActivityResult;
|
|
24
23
|
import androidx.activity.result.ActivityResultLauncher;
|
|
25
24
|
import androidx.activity.result.contract.ActivityResultContracts;
|
|
26
25
|
import androidx.annotation.NonNull;
|
|
@@ -63,8 +62,7 @@ import org.json.JSONObject;
|
|
|
63
62
|
@Permission(alias = "camera", strings = { Manifest.permission.CAMERA }),
|
|
64
63
|
@Permission(alias = "microphone", strings = { Manifest.permission.RECORD_AUDIO }),
|
|
65
64
|
@Permission(alias = "storage", strings = { Manifest.permission.READ_EXTERNAL_STORAGE })
|
|
66
|
-
}
|
|
67
|
-
requestCodes = { WebViewDialog.FILE_CHOOSER_REQUEST_CODE }
|
|
65
|
+
}
|
|
68
66
|
)
|
|
69
67
|
public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.PermissionHandler {
|
|
70
68
|
|
|
@@ -108,7 +106,6 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
108
106
|
private boolean currentPermissionNeedsCamera = false;
|
|
109
107
|
private boolean currentPermissionNeedsMicrophone = false;
|
|
110
108
|
|
|
111
|
-
private ActivityResultLauncher<Intent> fileChooserLauncher;
|
|
112
109
|
private ActivityResultLauncher<String[]> webPermissionLauncher;
|
|
113
110
|
private PluginCall pendingCameraPermissionCall;
|
|
114
111
|
|
|
@@ -118,10 +115,6 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
118
115
|
@Override
|
|
119
116
|
public void load() {
|
|
120
117
|
super.load();
|
|
121
|
-
fileChooserLauncher = getActivity().registerForActivityResult(
|
|
122
|
-
new ActivityResultContracts.StartActivityForResult(),
|
|
123
|
-
this::handleFileChooserResult
|
|
124
|
-
);
|
|
125
118
|
webPermissionLauncher = getActivity().registerForActivityResult(
|
|
126
119
|
new ActivityResultContracts.RequestMultiplePermissions(),
|
|
127
120
|
this::handleWebPermissionResult
|
|
@@ -355,6 +348,7 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
355
348
|
);
|
|
356
349
|
dialog.setInstanceId(webViewId);
|
|
357
350
|
dialog.activity = CapgoInAppBrowserPlugin.this.getActivity();
|
|
351
|
+
dialog.bindToHostActivity();
|
|
358
352
|
registerWebView(webViewId, dialog, makeActive);
|
|
359
353
|
return dialog;
|
|
360
354
|
}
|
|
@@ -525,59 +519,6 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
525
519
|
return targetWebViews;
|
|
526
520
|
}
|
|
527
521
|
|
|
528
|
-
private WebViewDialog findFileChooserDialog() {
|
|
529
|
-
if (activeWebViewId != null) {
|
|
530
|
-
WebViewDialog dialog = webViewDialogs.get(activeWebViewId);
|
|
531
|
-
if (dialog != null && dialog.mFilePathCallback != null) {
|
|
532
|
-
return dialog;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
if (webViewDialog != null && webViewDialog.mFilePathCallback != null) {
|
|
537
|
-
return webViewDialog;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
for (WebViewDialog dialog : webViewDialogs.values()) {
|
|
541
|
-
if (dialog != null && dialog.mFilePathCallback != null) {
|
|
542
|
-
return dialog;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
return null;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
private void handleFileChooserResult(ActivityResult result) {
|
|
550
|
-
WebViewDialog webViewDialog = findFileChooserDialog();
|
|
551
|
-
if (webViewDialog != null && webViewDialog.mFilePathCallback != null) {
|
|
552
|
-
Uri[] results = null;
|
|
553
|
-
Intent data = result.getData();
|
|
554
|
-
|
|
555
|
-
if (result.getResultCode() == Activity.RESULT_OK) {
|
|
556
|
-
// Handle camera capture result
|
|
557
|
-
if (webViewDialog.tempCameraUri != null && (data == null || data.getData() == null)) {
|
|
558
|
-
results = new Uri[] { webViewDialog.tempCameraUri };
|
|
559
|
-
}
|
|
560
|
-
// Handle regular file picker result
|
|
561
|
-
else if (data != null) {
|
|
562
|
-
if (data.getClipData() != null) {
|
|
563
|
-
// Handle multiple files
|
|
564
|
-
int count = data.getClipData().getItemCount();
|
|
565
|
-
results = new Uri[count];
|
|
566
|
-
for (int i = 0; i < count; i++) {
|
|
567
|
-
results[i] = data.getClipData().getItemAt(i).getUri();
|
|
568
|
-
}
|
|
569
|
-
} else if (data.getData() != null) {
|
|
570
|
-
// Handle single file
|
|
571
|
-
results = new Uri[] { data.getData() };
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
// Send the result to WebView and clean up
|
|
577
|
-
webViewDialog.completeLegacyFileChooserResult(results);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
522
|
public void handleMicrophonePermissionRequest(PermissionRequest request) {
|
|
582
523
|
if (request == null) {
|
|
583
524
|
return;
|
|
@@ -796,6 +737,16 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
796
737
|
);
|
|
797
738
|
}
|
|
798
739
|
|
|
740
|
+
private CustomTabColorSchemeParams buildCustomTabColorScheme(int colorInt) {
|
|
741
|
+
return applyCustomTabNavigationBarColor(new CustomTabColorSchemeParams.Builder().setToolbarColor(colorInt), colorInt).build();
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
@SuppressWarnings("deprecation")
|
|
745
|
+
private CustomTabColorSchemeParams.Builder applyCustomTabNavigationBarColor(CustomTabColorSchemeParams.Builder builder, int colorInt) {
|
|
746
|
+
// androidx.browser 1.9.0 still exposes only setNavigationBarColor; no non-deprecated replacement.
|
|
747
|
+
return builder.setNavigationBarColor(colorInt);
|
|
748
|
+
}
|
|
749
|
+
|
|
799
750
|
@PluginMethod
|
|
800
751
|
public void open(PluginCall call) {
|
|
801
752
|
String url = call.getString("url");
|
|
@@ -828,10 +779,7 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
828
779
|
if (toolbarColor != null) {
|
|
829
780
|
try {
|
|
830
781
|
int colorInt = Color.parseColor(toolbarColor);
|
|
831
|
-
CustomTabColorSchemeParams colorParams =
|
|
832
|
-
.setToolbarColor(colorInt)
|
|
833
|
-
.setNavigationBarColor(colorInt)
|
|
834
|
-
.build();
|
|
782
|
+
CustomTabColorSchemeParams colorParams = buildCustomTabColorScheme(colorInt);
|
|
835
783
|
builder.setDefaultColorSchemeParams(colorParams);
|
|
836
784
|
builder.setColorSchemeParams(CustomTabsIntent.COLOR_SCHEME_DARK, colorParams);
|
|
837
785
|
} catch (IllegalArgumentException e) {
|
|
@@ -11,7 +11,6 @@ import com.getcapacitor.annotation.Permission;
|
|
|
11
11
|
@Permission(alias = "camera", strings = { Manifest.permission.CAMERA }),
|
|
12
12
|
@Permission(alias = "microphone", strings = { Manifest.permission.RECORD_AUDIO }),
|
|
13
13
|
@Permission(alias = "storage", strings = { Manifest.permission.READ_EXTERNAL_STORAGE })
|
|
14
|
-
}
|
|
15
|
-
requestCodes = { WebViewDialog.FILE_CHOOSER_REQUEST_CODE }
|
|
14
|
+
}
|
|
16
15
|
)
|
|
17
16
|
public class InAppBrowserPlugin extends CapgoInAppBrowserPlugin {}
|
|
@@ -122,9 +122,14 @@ final class SafeAreaInsetsSupport {
|
|
|
122
122
|
* Whether the WebView container must be inset for the bottom system bar. On Android 15+ the dialog
|
|
123
123
|
* is forced edge-to-edge (decorFitsSystemWindows=false), so the window always draws under the
|
|
124
124
|
* navigation bar and insetting is mandatory to keep bottom content on-screen, regardless of the
|
|
125
|
-
* enabledSafeBottomMargin opt-in that older versions honour.
|
|
125
|
+
* enabledSafeBottomMargin opt-in that older versions honour. Pre-API 30 windows that lay out behind
|
|
126
|
+
* a transparent navigation bar need the same treatment.
|
|
126
127
|
*/
|
|
128
|
+
static boolean shouldInsetBottomForContainer(boolean enabledSafeBottomMargin, boolean isEdgeToEdge, boolean layoutBehindNavigationBar) {
|
|
129
|
+
return enabledSafeBottomMargin || isEdgeToEdge || layoutBehindNavigationBar;
|
|
130
|
+
}
|
|
131
|
+
|
|
127
132
|
static boolean shouldInsetBottomForContainer(boolean enabledSafeBottomMargin, boolean isEdgeToEdge) {
|
|
128
|
-
return enabledSafeBottomMargin
|
|
133
|
+
return shouldInsetBottomForContainer(enabledSafeBottomMargin, isEdgeToEdge, false);
|
|
129
134
|
}
|
|
130
135
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
package ee.forgr.capacitor_inappbrowser;
|
|
2
|
+
|
|
3
|
+
import android.graphics.Color;
|
|
4
|
+
import android.os.Build;
|
|
5
|
+
import android.view.View;
|
|
6
|
+
import android.view.Window;
|
|
7
|
+
import android.view.WindowManager;
|
|
8
|
+
import androidx.core.view.WindowCompat;
|
|
9
|
+
import androidx.core.view.WindowInsetsControllerCompat;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Centralizes window chrome decisions so WebViewDialog can avoid deprecated system UI APIs on
|
|
13
|
+
* Android 15+ while keeping API 24–34 behavior unchanged.
|
|
14
|
+
*/
|
|
15
|
+
final class SystemUiChromeSupport {
|
|
16
|
+
|
|
17
|
+
static final int EDGE_TO_EDGE_SDK = Build.VERSION_CODES.VANILLA_ICE_CREAM;
|
|
18
|
+
|
|
19
|
+
private SystemUiChromeSupport() {}
|
|
20
|
+
|
|
21
|
+
static boolean requiresEdgeToEdgeChrome(int sdkInt) {
|
|
22
|
+
return sdkInt >= EDGE_TO_EDGE_SDK;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static boolean shouldApplyLegacySystemBarColors(int sdkInt) {
|
|
26
|
+
return sdkInt < EDGE_TO_EDGE_SDK;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static boolean shouldUsePreApi30LayoutFlags(int sdkInt) {
|
|
30
|
+
return sdkInt < Build.VERSION_CODES.R;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static boolean usesLayoutBehindNavigationBar(int sdkInt, boolean edgeToEdge) {
|
|
34
|
+
return !edgeToEdge && shouldUsePreApi30LayoutFlags(sdkInt);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static void setDecorFitsSystemWindows(Window window, boolean decorFitsSystemWindows) {
|
|
38
|
+
if (window == null) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
WindowCompat.setDecorFitsSystemWindows(window, decorFitsSystemWindows);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static void prepareInitialDialogWindow(Window window) {
|
|
45
|
+
if (window == null) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
|
50
|
+
if (shouldApplyLegacySystemBarColors(Build.VERSION.SDK_INT)) {
|
|
51
|
+
applyLegacySystemBarColors(window, Color.TRANSPARENT, null);
|
|
52
|
+
clearLegacyTranslucentStatusFlag(window);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static void applyDialogWindowChrome(
|
|
57
|
+
Window window,
|
|
58
|
+
View decorView,
|
|
59
|
+
boolean edgeToEdge,
|
|
60
|
+
Integer statusBarColor,
|
|
61
|
+
Integer navigationBarColor,
|
|
62
|
+
Boolean lightStatusBars
|
|
63
|
+
) {
|
|
64
|
+
if (window == null || decorView == null) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (edgeToEdge) {
|
|
69
|
+
setDecorFitsSystemWindows(window, false);
|
|
70
|
+
} else if (!shouldUsePreApi30LayoutFlags(Build.VERSION.SDK_INT)) {
|
|
71
|
+
setDecorFitsSystemWindows(window, true);
|
|
72
|
+
applyLegacySystemBarColors(window, statusBarColor, navigationBarColor);
|
|
73
|
+
} else {
|
|
74
|
+
applyPreApi30LayoutBehindNavigationBar(decorView);
|
|
75
|
+
applyLegacySystemBarColors(window, statusBarColor, navigationBarColor);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(window, decorView);
|
|
79
|
+
if (lightStatusBars != null) {
|
|
80
|
+
controller.setAppearanceLightStatusBars(lightStatusBars);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@SuppressWarnings("deprecation")
|
|
85
|
+
private static void applyPreApi30LayoutBehindNavigationBar(View decorView) {
|
|
86
|
+
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@SuppressWarnings("deprecation")
|
|
90
|
+
static void applyLegacySystemBarColors(Window window, Integer statusBarColor, Integer navigationBarColor) {
|
|
91
|
+
if (window == null || !shouldApplyLegacySystemBarColors(Build.VERSION.SDK_INT)) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (statusBarColor != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
96
|
+
window.setStatusBarColor(statusBarColor);
|
|
97
|
+
}
|
|
98
|
+
if (navigationBarColor != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
99
|
+
window.setNavigationBarColor(navigationBarColor);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@SuppressWarnings("deprecation")
|
|
104
|
+
private static void clearLegacyTranslucentStatusFlag(Window window) {
|
|
105
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
106
|
+
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -69,7 +69,9 @@ import android.widget.RelativeLayout;
|
|
|
69
69
|
import android.widget.TextView;
|
|
70
70
|
import android.widget.Toast;
|
|
71
71
|
import android.widget.Toolbar;
|
|
72
|
+
import androidx.activity.ComponentActivity;
|
|
72
73
|
import androidx.activity.result.ActivityResult;
|
|
74
|
+
import androidx.activity.result.ActivityResultLauncher;
|
|
73
75
|
import androidx.activity.result.contract.ActivityResultContracts;
|
|
74
76
|
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
|
75
77
|
import androidx.core.content.FileProvider;
|
|
@@ -409,10 +411,11 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
409
411
|
private boolean preShowInjectedAtDocumentStart = false;
|
|
410
412
|
|
|
411
413
|
public PermissionRequest currentPermissionRequest;
|
|
412
|
-
public static final int FILE_CHOOSER_REQUEST_CODE = 1000;
|
|
413
414
|
public ValueCallback<Uri> mUploadMessage;
|
|
414
415
|
public ValueCallback<Uri[]> mFilePathCallback;
|
|
415
416
|
FileChooserRequestSupport.FileChooserRequest activeFileChooserRequest;
|
|
417
|
+
private ActivityResultLauncher<Intent> cameraCaptureLauncher;
|
|
418
|
+
private ActivityResultLauncher<Intent> fileChooserLauncher;
|
|
416
419
|
private boolean openWebViewResolved;
|
|
417
420
|
private boolean isDismissing = false;
|
|
418
421
|
private PermissionRequest pendingCameraLaunchPermissionRequest;
|
|
@@ -447,6 +450,11 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
447
450
|
this.instanceId = id != null ? id : "";
|
|
448
451
|
}
|
|
449
452
|
|
|
453
|
+
void bindToHostActivity() {
|
|
454
|
+
ensureFileChooserLaunchers();
|
|
455
|
+
registerDialogBackHandler();
|
|
456
|
+
}
|
|
457
|
+
|
|
450
458
|
public String getInstanceId() {
|
|
451
459
|
return instanceId;
|
|
452
460
|
}
|
|
@@ -2116,10 +2124,6 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2116
2124
|
public void presentWebView() {
|
|
2117
2125
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
2118
2126
|
setCancelable(true);
|
|
2119
|
-
Objects.requireNonNull(getWindow()).setFlags(
|
|
2120
|
-
WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
|
2121
|
-
WindowManager.LayoutParams.FLAG_FULLSCREEN
|
|
2122
|
-
);
|
|
2123
2127
|
setContentView(R.layout.activity_browser);
|
|
2124
2128
|
|
|
2125
2129
|
// If custom dimensions are set, configure for touch passthrough
|
|
@@ -2143,18 +2147,10 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2143
2147
|
if (appBar != null) appBar.setFitsSystemWindows(true);
|
|
2144
2148
|
}
|
|
2145
2149
|
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
// Make status bar transparent
|
|
2149
|
-
if (getWindow() != null) {
|
|
2150
|
-
getWindow().setStatusBarColor(Color.TRANSPARENT);
|
|
2151
|
-
|
|
2152
|
-
// Add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
|
|
2153
|
-
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
|
2150
|
+
// Set dimensions if specified, otherwise fullscreen
|
|
2151
|
+
applyDimensions();
|
|
2154
2152
|
|
|
2155
|
-
|
|
2156
|
-
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
|
2157
|
-
}
|
|
2153
|
+
SystemUiChromeSupport.prepareInitialDialogWindow(getWindow());
|
|
2158
2154
|
|
|
2159
2155
|
WindowInsetsControllerCompat insetsController = new WindowInsetsControllerCompat(
|
|
2160
2156
|
getWindow(),
|
|
@@ -2206,9 +2202,6 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2206
2202
|
});
|
|
2207
2203
|
}
|
|
2208
2204
|
|
|
2209
|
-
// Set dimensions if specified, otherwise fullscreen
|
|
2210
|
-
applyDimensions();
|
|
2211
|
-
|
|
2212
2205
|
this._webView = findViewById(R.id.browser_view);
|
|
2213
2206
|
|
|
2214
2207
|
this.swipeRefreshLayout = findViewById(R.id.content_browser_layout);
|
|
@@ -2583,38 +2576,12 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2583
2576
|
}
|
|
2584
2577
|
|
|
2585
2578
|
try {
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
componentActivity
|
|
2590
|
-
.getActivityResultRegistry()
|
|
2591
|
-
.register(
|
|
2592
|
-
"camera_capture",
|
|
2593
|
-
new androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult(),
|
|
2594
|
-
(result) -> {
|
|
2595
|
-
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
2596
|
-
return;
|
|
2597
|
-
}
|
|
2598
|
-
Uri[] results = null;
|
|
2599
|
-
if (result.getResultCode() == Activity.RESULT_OK && request.tempCameraUri != null) {
|
|
2600
|
-
results = new Uri[] { request.tempCameraUri };
|
|
2601
|
-
}
|
|
2602
|
-
if (
|
|
2603
|
-
FileChooserRequestSupport.completeIfActive(
|
|
2604
|
-
request,
|
|
2605
|
-
activeFileChooserRequest,
|
|
2606
|
-
results
|
|
2607
|
-
)
|
|
2608
|
-
) {
|
|
2609
|
-
request.tempCameraUri = null;
|
|
2610
|
-
clearActiveFileChooserRequest(request);
|
|
2611
|
-
}
|
|
2612
|
-
}
|
|
2613
|
-
)
|
|
2614
|
-
.launch(takePictureIntent);
|
|
2579
|
+
ensureFileChooserLaunchers();
|
|
2580
|
+
if (cameraCaptureLauncher != null) {
|
|
2581
|
+
cameraCaptureLauncher.launch(takePictureIntent);
|
|
2615
2582
|
} else {
|
|
2616
|
-
|
|
2617
|
-
|
|
2583
|
+
Log.e("InAppBrowser", "ComponentActivity required for camera capture, falling back to file picker");
|
|
2584
|
+
fallbackToFilePicker(request);
|
|
2618
2585
|
}
|
|
2619
2586
|
} catch (SecurityException e) {
|
|
2620
2587
|
Log.e("InAppBrowser", "Security exception launching camera: " + e.getMessage(), e);
|
|
@@ -2887,6 +2854,52 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
2887
2854
|
registerConfigurationCallbacks();
|
|
2888
2855
|
}
|
|
2889
2856
|
|
|
2857
|
+
private void registerDialogBackHandler() {
|
|
2858
|
+
setOnKeyListener((dialogInterface, keyCode, event) -> {
|
|
2859
|
+
if (keyCode != KeyEvent.KEYCODE_BACK) {
|
|
2860
|
+
return false;
|
|
2861
|
+
}
|
|
2862
|
+
if (event.getAction() != KeyEvent.ACTION_UP) {
|
|
2863
|
+
return true;
|
|
2864
|
+
}
|
|
2865
|
+
if (!shouldConsumeBackPress()) {
|
|
2866
|
+
return false;
|
|
2867
|
+
}
|
|
2868
|
+
handleBrowserBackNavigation();
|
|
2869
|
+
return true;
|
|
2870
|
+
});
|
|
2871
|
+
}
|
|
2872
|
+
|
|
2873
|
+
private boolean shouldConsumeBackPress() {
|
|
2874
|
+
return isShowing() && !isHiddenModeActive && !backLayerActive;
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2877
|
+
private void handleBrowserBackNavigation() {
|
|
2878
|
+
if (_options == null) {
|
|
2879
|
+
dismiss();
|
|
2880
|
+
return;
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
if (
|
|
2884
|
+
_webView != null &&
|
|
2885
|
+
_webView.canGoBack() &&
|
|
2886
|
+
(TextUtils.equals(_options.getToolbarType(), "navigation") || _options.getActiveNativeNavigationForWebview())
|
|
2887
|
+
) {
|
|
2888
|
+
_webView.goBack();
|
|
2889
|
+
return;
|
|
2890
|
+
}
|
|
2891
|
+
|
|
2892
|
+
if (_options.getDisableGoBackOnNativeApplication()) {
|
|
2893
|
+
return;
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
String currentUrl = getUrl();
|
|
2897
|
+
if (_options.getCallbacks() != null) {
|
|
2898
|
+
_options.getCallbacks().closeEvent(currentUrl);
|
|
2899
|
+
}
|
|
2900
|
+
dismiss();
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2890
2903
|
private void applyHiddenMode() {
|
|
2891
2904
|
Window window = getWindow();
|
|
2892
2905
|
if (window == null) {
|
|
@@ -3033,7 +3046,7 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
3033
3046
|
}
|
|
3034
3047
|
|
|
3035
3048
|
// Check if we need Android 15+ specific fixes
|
|
3036
|
-
boolean isAndroid15Plus = Build.VERSION.SDK_INT
|
|
3049
|
+
boolean isAndroid15Plus = SystemUiChromeSupport.requiresEdgeToEdgeChrome(Build.VERSION.SDK_INT);
|
|
3037
3050
|
|
|
3038
3051
|
View toolbarView = findViewById(R.id.tool_bar);
|
|
3039
3052
|
|
|
@@ -3062,69 +3075,54 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
3062
3075
|
|
|
3063
3076
|
// Handle window decoration - version-specific handling
|
|
3064
3077
|
if (getWindow() != null) {
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
getWindow().setNavigationBarColor(Color.TRANSPARENT);
|
|
3070
|
-
|
|
3071
|
-
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(getWindow(), getWindow().getDecorView());
|
|
3078
|
+
View decorView = getWindow().getDecorView();
|
|
3079
|
+
Integer statusBarColor = null;
|
|
3080
|
+
Integer navigationBarColor = Color.TRANSPARENT;
|
|
3081
|
+
Boolean lightStatusBars = null;
|
|
3072
3082
|
|
|
3073
|
-
|
|
3083
|
+
if (isAndroid15Plus) {
|
|
3074
3084
|
if (_options.getToolbarColor() != null && !_options.getToolbarColor().isEmpty()) {
|
|
3075
3085
|
try {
|
|
3076
3086
|
int backgroundColor = Color.parseColor(_options.getToolbarColor());
|
|
3077
|
-
|
|
3078
|
-
controller.setAppearanceLightStatusBars(!isDarkBackground);
|
|
3087
|
+
lightStatusBars = !isDarkColor(backgroundColor);
|
|
3079
3088
|
} catch (IllegalArgumentException e) {
|
|
3080
3089
|
// Ignore color parsing errors
|
|
3081
3090
|
}
|
|
3082
3091
|
}
|
|
3083
|
-
} else if (Build.VERSION.SDK_INT >=
|
|
3084
|
-
// Android 11-14: Keep navigation bar transparent but respect status bar
|
|
3085
|
-
getWindow().setNavigationBarColor(Color.TRANSPARENT);
|
|
3086
|
-
|
|
3087
|
-
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(getWindow(), getWindow().getDecorView());
|
|
3088
|
-
|
|
3089
|
-
// Set status bar color to match toolbar or use system default
|
|
3092
|
+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
3090
3093
|
if (_options.getToolbarColor() != null && !_options.getToolbarColor().isEmpty()) {
|
|
3091
3094
|
try {
|
|
3092
3095
|
int toolbarColor = Color.parseColor(_options.getToolbarColor());
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
controller.setAppearanceLightStatusBars(!isDarkBackground);
|
|
3096
|
+
statusBarColor = toolbarColor;
|
|
3097
|
+
lightStatusBars = !isDarkColor(toolbarColor);
|
|
3096
3098
|
} catch (IllegalArgumentException e) {
|
|
3097
|
-
// Follow system theme if color parsing fails
|
|
3098
3099
|
boolean isDarkTheme = isDarkThemeEnabled();
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
controller.setAppearanceLightStatusBars(!isDarkTheme);
|
|
3100
|
+
statusBarColor = isDarkTheme ? Color.BLACK : Color.WHITE;
|
|
3101
|
+
lightStatusBars = !isDarkTheme;
|
|
3102
3102
|
}
|
|
3103
3103
|
} else {
|
|
3104
|
-
// Follow system theme if no toolbar color provided
|
|
3105
3104
|
boolean isDarkTheme = isDarkThemeEnabled();
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
controller.setAppearanceLightStatusBars(!isDarkTheme);
|
|
3105
|
+
statusBarColor = isDarkTheme ? Color.BLACK : Color.WHITE;
|
|
3106
|
+
lightStatusBars = !isDarkTheme;
|
|
3109
3107
|
}
|
|
3110
3108
|
} else {
|
|
3111
|
-
// Pre-Android 11: Use deprecated flags for edge-to-edge navigation bar only
|
|
3112
|
-
getWindow()
|
|
3113
|
-
.getDecorView()
|
|
3114
|
-
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
|
3115
|
-
|
|
3116
|
-
getWindow().setNavigationBarColor(Color.TRANSPARENT);
|
|
3117
|
-
|
|
3118
|
-
// Set status bar color to match toolbar
|
|
3119
3109
|
if (_options.getToolbarColor() != null && !_options.getToolbarColor().isEmpty()) {
|
|
3120
3110
|
try {
|
|
3121
|
-
|
|
3122
|
-
getWindow().setStatusBarColor(toolbarColor);
|
|
3111
|
+
statusBarColor = Color.parseColor(_options.getToolbarColor());
|
|
3123
3112
|
} catch (IllegalArgumentException e) {
|
|
3124
3113
|
// Use system default
|
|
3125
3114
|
}
|
|
3126
3115
|
}
|
|
3127
3116
|
}
|
|
3117
|
+
|
|
3118
|
+
SystemUiChromeSupport.applyDialogWindowChrome(
|
|
3119
|
+
getWindow(),
|
|
3120
|
+
decorView,
|
|
3121
|
+
isAndroid15Plus,
|
|
3122
|
+
statusBarColor,
|
|
3123
|
+
navigationBarColor,
|
|
3124
|
+
lightStatusBars
|
|
3125
|
+
);
|
|
3128
3126
|
}
|
|
3129
3127
|
|
|
3130
3128
|
requestSafeAreaInsets();
|
|
@@ -3443,7 +3441,7 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
3443
3441
|
return;
|
|
3444
3442
|
}
|
|
3445
3443
|
|
|
3446
|
-
boolean isAndroid15Plus = Build.VERSION.SDK_INT
|
|
3444
|
+
boolean isAndroid15Plus = SystemUiChromeSupport.requiresEdgeToEdgeChrome(Build.VERSION.SDK_INT);
|
|
3447
3445
|
View toolbarView = findBrowserContentDescendant(R.id.tool_bar);
|
|
3448
3446
|
applyWindowInsetsToWebView(windowInsets, isAndroid15Plus, toolbarView);
|
|
3449
3447
|
}
|
|
@@ -3515,7 +3513,13 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
3515
3513
|
return;
|
|
3516
3514
|
}
|
|
3517
3515
|
|
|
3518
|
-
boolean
|
|
3516
|
+
boolean layoutBehindNavigationBar =
|
|
3517
|
+
!backLayerActive && SystemUiChromeSupport.usesLayoutBehindNavigationBar(Build.VERSION.SDK_INT, isEdgeToEdge);
|
|
3518
|
+
boolean applyBottomInset = SafeAreaInsetsSupport.shouldInsetBottomForContainer(
|
|
3519
|
+
_options.getEnabledSafeMargin(),
|
|
3520
|
+
isEdgeToEdge,
|
|
3521
|
+
layoutBehindNavigationBar
|
|
3522
|
+
);
|
|
3519
3523
|
int statusBarTop = SafeAreaInsetsSupport.resolveStatusBarTop(
|
|
3520
3524
|
bars.top,
|
|
3521
3525
|
bars.bottom,
|
|
@@ -4086,6 +4090,88 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
4086
4090
|
}
|
|
4087
4091
|
}
|
|
4088
4092
|
|
|
4093
|
+
private void ensureFileChooserLaunchers() {
|
|
4094
|
+
if (!(activity instanceof ComponentActivity componentActivity)) {
|
|
4095
|
+
return;
|
|
4096
|
+
}
|
|
4097
|
+
if (fileChooserLauncher != null && cameraCaptureLauncher != null) {
|
|
4098
|
+
return;
|
|
4099
|
+
}
|
|
4100
|
+
|
|
4101
|
+
String launcherSuffix = (instanceId != null && !instanceId.isEmpty() ? instanceId + "_" : "") + Integer.toHexString(hashCode());
|
|
4102
|
+
if (cameraCaptureLauncher == null) {
|
|
4103
|
+
cameraCaptureLauncher = componentActivity
|
|
4104
|
+
.getActivityResultRegistry()
|
|
4105
|
+
.register(
|
|
4106
|
+
"inappbrowser_camera_capture_" + launcherSuffix,
|
|
4107
|
+
new ActivityResultContracts.StartActivityForResult(),
|
|
4108
|
+
this::handleCameraCaptureActivityResult
|
|
4109
|
+
);
|
|
4110
|
+
}
|
|
4111
|
+
if (fileChooserLauncher == null) {
|
|
4112
|
+
fileChooserLauncher = componentActivity
|
|
4113
|
+
.getActivityResultRegistry()
|
|
4114
|
+
.register(
|
|
4115
|
+
"inappbrowser_file_chooser_" + launcherSuffix,
|
|
4116
|
+
new ActivityResultContracts.StartActivityForResult(),
|
|
4117
|
+
this::handleFileChooserActivityResult
|
|
4118
|
+
);
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
|
|
4122
|
+
private void clearActivityResultLaunchers() {
|
|
4123
|
+
if (cameraCaptureLauncher != null) {
|
|
4124
|
+
cameraCaptureLauncher.unregister();
|
|
4125
|
+
cameraCaptureLauncher = null;
|
|
4126
|
+
}
|
|
4127
|
+
if (fileChooserLauncher != null) {
|
|
4128
|
+
fileChooserLauncher.unregister();
|
|
4129
|
+
fileChooserLauncher = null;
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
|
|
4133
|
+
private void handleCameraCaptureActivityResult(ActivityResult result) {
|
|
4134
|
+
FileChooserRequestSupport.FileChooserRequest request = activeFileChooserRequest;
|
|
4135
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
4136
|
+
return;
|
|
4137
|
+
}
|
|
4138
|
+
|
|
4139
|
+
Uri[] results = null;
|
|
4140
|
+
if (result.getResultCode() == Activity.RESULT_OK && request.tempCameraUri != null) {
|
|
4141
|
+
results = new Uri[] { request.tempCameraUri };
|
|
4142
|
+
}
|
|
4143
|
+
if (FileChooserRequestSupport.completeIfActive(request, activeFileChooserRequest, results)) {
|
|
4144
|
+
request.tempCameraUri = null;
|
|
4145
|
+
clearActiveFileChooserRequest(request);
|
|
4146
|
+
}
|
|
4147
|
+
}
|
|
4148
|
+
|
|
4149
|
+
private void handleFileChooserActivityResult(ActivityResult result) {
|
|
4150
|
+
FileChooserRequestSupport.FileChooserRequest request = activeFileChooserRequest;
|
|
4151
|
+
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
4152
|
+
return;
|
|
4153
|
+
}
|
|
4154
|
+
|
|
4155
|
+
Uri[] results = null;
|
|
4156
|
+
if (result.getResultCode() == Activity.RESULT_OK) {
|
|
4157
|
+
Intent data = result.getData();
|
|
4158
|
+
if (data != null) {
|
|
4159
|
+
if (data.getClipData() != null) {
|
|
4160
|
+
int count = data.getClipData().getItemCount();
|
|
4161
|
+
results = new Uri[count];
|
|
4162
|
+
for (int i = 0; i < count; i++) {
|
|
4163
|
+
results[i] = data.getClipData().getItemAt(i).getUri();
|
|
4164
|
+
}
|
|
4165
|
+
} else if (data.getData() != null) {
|
|
4166
|
+
results = new Uri[] { data.getData() };
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
if (FileChooserRequestSupport.completeIfActive(request, activeFileChooserRequest, results)) {
|
|
4171
|
+
clearActiveFileChooserRequest(request);
|
|
4172
|
+
}
|
|
4173
|
+
}
|
|
4174
|
+
|
|
4089
4175
|
private void beginFileChooserRequest(ValueCallback<Uri[]> filePathCallback, String[] acceptTypes, boolean isMultiple) {
|
|
4090
4176
|
if (activeFileChooserRequest != null) {
|
|
4091
4177
|
FileChooserRequestSupport.cancel(activeFileChooserRequest);
|
|
@@ -4106,17 +4192,6 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
4106
4192
|
tempCameraUri = activeFileChooserRequest != null ? activeFileChooserRequest.tempCameraUri : null;
|
|
4107
4193
|
}
|
|
4108
4194
|
|
|
4109
|
-
void completeLegacyFileChooserResult(Uri[] results) {
|
|
4110
|
-
FileChooserRequestSupport.FileChooserRequest request = activeFileChooserRequest;
|
|
4111
|
-
if (request == null) {
|
|
4112
|
-
return;
|
|
4113
|
-
}
|
|
4114
|
-
if (FileChooserRequestSupport.completeIfActive(request, activeFileChooserRequest, results)) {
|
|
4115
|
-
request.tempCameraUri = null;
|
|
4116
|
-
clearActiveFileChooserRequest(request);
|
|
4117
|
-
}
|
|
4118
|
-
}
|
|
4119
|
-
|
|
4120
4195
|
private void openFileChooser(FileChooserRequestSupport.FileChooserRequest request) {
|
|
4121
4196
|
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
4122
4197
|
return;
|
|
@@ -4127,88 +4202,14 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
4127
4202
|
Log.d("InAppBrowser", "File picker using action: " + intent.getAction() + ", MIME types: " + mimeTypes);
|
|
4128
4203
|
|
|
4129
4204
|
try {
|
|
4130
|
-
|
|
4131
|
-
androidx.activity.ComponentActivity componentActivity = (androidx.activity.ComponentActivity) activity;
|
|
4132
|
-
componentActivity
|
|
4133
|
-
.getActivityResultRegistry()
|
|
4134
|
-
.register(
|
|
4135
|
-
"file_chooser",
|
|
4136
|
-
new androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult(),
|
|
4137
|
-
(result) -> {
|
|
4138
|
-
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
4139
|
-
return;
|
|
4140
|
-
}
|
|
4141
|
-
Uri[] results = null;
|
|
4142
|
-
if (result.getResultCode() == Activity.RESULT_OK) {
|
|
4143
|
-
Intent data = result.getData();
|
|
4144
|
-
if (data != null) {
|
|
4145
|
-
if (data.getClipData() != null) {
|
|
4146
|
-
// Handle multiple files
|
|
4147
|
-
int count = data.getClipData().getItemCount();
|
|
4148
|
-
results = new Uri[count];
|
|
4149
|
-
for (int i = 0; i < count; i++) {
|
|
4150
|
-
results[i] = data.getClipData().getItemAt(i).getUri();
|
|
4151
|
-
}
|
|
4152
|
-
} else if (data.getData() != null) {
|
|
4153
|
-
// Handle single file
|
|
4154
|
-
results = new Uri[] { data.getData() };
|
|
4155
|
-
}
|
|
4156
|
-
}
|
|
4157
|
-
}
|
|
4158
|
-
if (FileChooserRequestSupport.completeIfActive(request, activeFileChooserRequest, results)) {
|
|
4159
|
-
clearActiveFileChooserRequest(request);
|
|
4160
|
-
}
|
|
4161
|
-
}
|
|
4162
|
-
)
|
|
4163
|
-
.launch(Intent.createChooser(intent, "Select File"));
|
|
4164
|
-
} else {
|
|
4165
|
-
// Fallback for non-ComponentActivity
|
|
4166
|
-
activity.startActivityForResult(Intent.createChooser(intent, "Select File"), FILE_CHOOSER_REQUEST_CODE);
|
|
4167
|
-
}
|
|
4205
|
+
launchFileChooserIntent(Intent.createChooser(intent, "Select File"), request);
|
|
4168
4206
|
} catch (ActivityNotFoundException e) {
|
|
4169
4207
|
// If no app can handle the specific MIME type, try with a more generic one
|
|
4170
4208
|
Log.e("InAppBrowser", "No app available for types: " + mimeTypes + ", trying with */*");
|
|
4171
4209
|
intent.setType("*/*");
|
|
4172
4210
|
intent.removeExtra(Intent.EXTRA_MIME_TYPES);
|
|
4173
4211
|
try {
|
|
4174
|
-
|
|
4175
|
-
androidx.activity.ComponentActivity componentActivity = (androidx.activity.ComponentActivity) activity;
|
|
4176
|
-
componentActivity
|
|
4177
|
-
.getActivityResultRegistry()
|
|
4178
|
-
.register(
|
|
4179
|
-
"file_chooser",
|
|
4180
|
-
new androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult(),
|
|
4181
|
-
(result) -> {
|
|
4182
|
-
if (!FileChooserRequestSupport.isActive(request, activeFileChooserRequest)) {
|
|
4183
|
-
return;
|
|
4184
|
-
}
|
|
4185
|
-
Uri[] results = null;
|
|
4186
|
-
if (result.getResultCode() == Activity.RESULT_OK) {
|
|
4187
|
-
Intent data = result.getData();
|
|
4188
|
-
if (data != null) {
|
|
4189
|
-
if (data.getClipData() != null) {
|
|
4190
|
-
// Handle multiple files
|
|
4191
|
-
int count = data.getClipData().getItemCount();
|
|
4192
|
-
results = new Uri[count];
|
|
4193
|
-
for (int i = 0; i < count; i++) {
|
|
4194
|
-
results[i] = data.getClipData().getItemAt(i).getUri();
|
|
4195
|
-
}
|
|
4196
|
-
} else if (data.getData() != null) {
|
|
4197
|
-
// Handle single file
|
|
4198
|
-
results = new Uri[] { data.getData() };
|
|
4199
|
-
}
|
|
4200
|
-
}
|
|
4201
|
-
}
|
|
4202
|
-
if (FileChooserRequestSupport.completeIfActive(request, activeFileChooserRequest, results)) {
|
|
4203
|
-
clearActiveFileChooserRequest(request);
|
|
4204
|
-
}
|
|
4205
|
-
}
|
|
4206
|
-
)
|
|
4207
|
-
.launch(Intent.createChooser(intent, "Select File"));
|
|
4208
|
-
} else {
|
|
4209
|
-
// Fallback for non-ComponentActivity
|
|
4210
|
-
activity.startActivityForResult(Intent.createChooser(intent, "Select File"), FILE_CHOOSER_REQUEST_CODE);
|
|
4211
|
-
}
|
|
4212
|
+
launchFileChooserIntent(Intent.createChooser(intent, "Select File"), request);
|
|
4212
4213
|
} catch (ActivityNotFoundException ex) {
|
|
4213
4214
|
// If still failing, report error
|
|
4214
4215
|
Log.e("InAppBrowser", "No app can handle file picker", ex);
|
|
@@ -4219,6 +4220,18 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
4219
4220
|
}
|
|
4220
4221
|
}
|
|
4221
4222
|
|
|
4223
|
+
private void launchFileChooserIntent(Intent chooserIntent, FileChooserRequestSupport.FileChooserRequest request) {
|
|
4224
|
+
ensureFileChooserLaunchers();
|
|
4225
|
+
if (fileChooserLauncher == null) {
|
|
4226
|
+
Log.e("InAppBrowser", "ComponentActivity required for file chooser");
|
|
4227
|
+
if (FileChooserRequestSupport.cancelIfActive(request, activeFileChooserRequest)) {
|
|
4228
|
+
clearActiveFileChooserRequest(request);
|
|
4229
|
+
}
|
|
4230
|
+
return;
|
|
4231
|
+
}
|
|
4232
|
+
fileChooserLauncher.launch(chooserIntent);
|
|
4233
|
+
}
|
|
4234
|
+
|
|
4222
4235
|
public void reload() {
|
|
4223
4236
|
if (_webView == null) {
|
|
4224
4237
|
Log.w("InAppBrowser", "Cannot reload - WebView is null");
|
|
@@ -4700,8 +4713,7 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
4700
4713
|
|
|
4701
4714
|
// Also ensure status bar gets the color
|
|
4702
4715
|
if (getWindow() != null) {
|
|
4703
|
-
|
|
4704
|
-
getWindow().setStatusBarColor(toolbarColor);
|
|
4716
|
+
SystemUiChromeSupport.applyLegacySystemBarColors(getWindow(), toolbarColor, null);
|
|
4705
4717
|
|
|
4706
4718
|
// Determine proper status bar text color (light or dark icons)
|
|
4707
4719
|
boolean isDarkBackground = isDarkColor(toolbarColor);
|
|
@@ -6165,21 +6177,6 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
6165
6177
|
return false;
|
|
6166
6178
|
}
|
|
6167
6179
|
|
|
6168
|
-
@Override
|
|
6169
|
-
public void onBackPressed() {
|
|
6170
|
-
if (
|
|
6171
|
-
_webView != null &&
|
|
6172
|
-
_webView.canGoBack() &&
|
|
6173
|
-
(TextUtils.equals(_options.getToolbarType(), "navigation") || _options.getActiveNativeNavigationForWebview())
|
|
6174
|
-
) {
|
|
6175
|
-
_webView.goBack();
|
|
6176
|
-
} else if (!_options.getDisableGoBackOnNativeApplication()) {
|
|
6177
|
-
String currentUrl = getUrl();
|
|
6178
|
-
_options.getCallbacks().closeEvent(currentUrl);
|
|
6179
|
-
super.onBackPressed();
|
|
6180
|
-
}
|
|
6181
|
-
}
|
|
6182
|
-
|
|
6183
6180
|
@Override
|
|
6184
6181
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
6185
6182
|
// Forward volume key events to the MainActivity
|
|
@@ -6384,6 +6381,8 @@ public class WebViewDialog extends Dialog implements ProxyResponseRouting.ProxyR
|
|
|
6384
6381
|
// Clear any remaining proxied requests
|
|
6385
6382
|
proxiedRequestsHashmap.clear();
|
|
6386
6383
|
|
|
6384
|
+
clearActivityResultLaunchers();
|
|
6385
|
+
|
|
6387
6386
|
try {
|
|
6388
6387
|
super.dismiss();
|
|
6389
6388
|
} catch (Exception e) {
|
|
@@ -415,7 +415,7 @@ public class CapgoInAppBrowserPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
415
415
|
case aware = "AWARE"
|
|
416
416
|
case fakeVisible = "FAKE_VISIBLE"
|
|
417
417
|
}
|
|
418
|
-
private let pluginVersion: String = "8.15.
|
|
418
|
+
private let pluginVersion: String = "8.15.4"
|
|
419
419
|
public let identifier = "CapgoInAppBrowserPlugin"
|
|
420
420
|
public let jsName = "CapgoInAppBrowser"
|
|
421
421
|
public let pluginMethods: [CAPPluginMethod] = [
|