@capgo/inappbrowser 7.22.0 → 7.22.3
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/README.md +13 -13
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/InAppBrowserPlugin.java +769 -954
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +383 -409
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewCallbacks.java +7 -7
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +2565 -3135
- package/dist/docs.json +13 -13
- package/dist/esm/definitions.d.ts +10 -10
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +2 -2
- package/dist/esm/web.js +12 -12
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +12 -12
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +12 -12
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/InAppBrowserPlugin/InAppBrowserPlugin.swift +1 -1
- package/ios/Sources/InAppBrowserPlugin/WKWebViewController.swift +1 -1
- package/package.json +2 -2
|
@@ -40,1065 +40,880 @@ import org.json.JSONException;
|
|
|
40
40
|
import org.json.JSONObject;
|
|
41
41
|
|
|
42
42
|
@CapacitorPlugin(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
@Permission(
|
|
51
|
-
alias = "storage",
|
|
52
|
-
strings = { Manifest.permission.READ_EXTERNAL_STORAGE }
|
|
53
|
-
),
|
|
54
|
-
},
|
|
55
|
-
requestCodes = { WebViewDialog.FILE_CHOOSER_REQUEST_CODE }
|
|
43
|
+
name = "InAppBrowser",
|
|
44
|
+
permissions = {
|
|
45
|
+
@Permission(alias = "camera", strings = { Manifest.permission.CAMERA }),
|
|
46
|
+
@Permission(alias = "microphone", strings = { Manifest.permission.RECORD_AUDIO }),
|
|
47
|
+
@Permission(alias = "storage", strings = { Manifest.permission.READ_EXTERNAL_STORAGE })
|
|
48
|
+
},
|
|
49
|
+
requestCodes = { WebViewDialog.FILE_CHOOSER_REQUEST_CODE }
|
|
56
50
|
)
|
|
57
|
-
public class InAppBrowserPlugin
|
|
58
|
-
extends Plugin
|
|
59
|
-
implements WebViewDialog.PermissionHandler {
|
|
60
|
-
|
|
61
|
-
public static final String CUSTOM_TAB_PACKAGE_NAME = "com.android.chrome"; // Change when in stable
|
|
62
|
-
private CustomTabsClient customTabsClient;
|
|
63
|
-
private CustomTabsSession currentSession;
|
|
64
|
-
private WebViewDialog webViewDialog = null;
|
|
65
|
-
private String currentUrl = "";
|
|
66
|
-
|
|
67
|
-
private PermissionRequest currentPermissionRequest;
|
|
68
|
-
|
|
69
|
-
private ActivityResultLauncher<Intent> fileChooserLauncher;
|
|
70
|
-
|
|
71
|
-
@Override
|
|
72
|
-
public void load() {
|
|
73
|
-
super.load();
|
|
74
|
-
fileChooserLauncher = getActivity()
|
|
75
|
-
.registerForActivityResult(
|
|
76
|
-
new ActivityResultContracts.StartActivityForResult(),
|
|
77
|
-
this::handleFileChooserResult
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
private void handleFileChooserResult(ActivityResult result) {
|
|
82
|
-
if (webViewDialog != null && webViewDialog.mFilePathCallback != null) {
|
|
83
|
-
Uri[] results = null;
|
|
84
|
-
Intent data = result.getData();
|
|
85
|
-
|
|
86
|
-
if (result.getResultCode() == Activity.RESULT_OK) {
|
|
87
|
-
// Handle camera capture result
|
|
88
|
-
if (
|
|
89
|
-
webViewDialog.tempCameraUri != null &&
|
|
90
|
-
(data == null || data.getData() == null)
|
|
91
|
-
) {
|
|
92
|
-
results = new Uri[] { webViewDialog.tempCameraUri };
|
|
93
|
-
}
|
|
94
|
-
// Handle regular file picker result
|
|
95
|
-
else if (data != null) {
|
|
96
|
-
if (data.getClipData() != null) {
|
|
97
|
-
// Handle multiple files
|
|
98
|
-
int count = data.getClipData().getItemCount();
|
|
99
|
-
results = new Uri[count];
|
|
100
|
-
for (int i = 0; i < count; i++) {
|
|
101
|
-
results[i] = data.getClipData().getItemAt(i).getUri();
|
|
102
|
-
}
|
|
103
|
-
} else if (data.getData() != null) {
|
|
104
|
-
// Handle single file
|
|
105
|
-
results = new Uri[] { data.getData() };
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
51
|
+
public class InAppBrowserPlugin extends Plugin implements WebViewDialog.PermissionHandler {
|
|
109
52
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
public void handleMicrophonePermissionRequest(PermissionRequest request) {
|
|
118
|
-
this.currentPermissionRequest = request;
|
|
119
|
-
if (getPermissionState("microphone") != PermissionState.GRANTED) {
|
|
120
|
-
requestPermissionForAlias(
|
|
121
|
-
"microphone",
|
|
122
|
-
null,
|
|
123
|
-
"microphonePermissionCallback"
|
|
124
|
-
);
|
|
125
|
-
} else {
|
|
126
|
-
grantMicrophonePermission();
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
private void grantMicrophonePermission() {
|
|
131
|
-
if (currentPermissionRequest != null) {
|
|
132
|
-
currentPermissionRequest.grant(
|
|
133
|
-
new String[] { PermissionRequest.RESOURCE_AUDIO_CAPTURE }
|
|
134
|
-
);
|
|
135
|
-
currentPermissionRequest = null;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
@PermissionCallback
|
|
140
|
-
private void microphonePermissionCallback(PluginCall call) {
|
|
141
|
-
if (getPermissionState("microphone") == PermissionState.GRANTED) {
|
|
142
|
-
grantCameraAndMicrophonePermission();
|
|
143
|
-
} else {
|
|
144
|
-
if (currentPermissionRequest != null) {
|
|
145
|
-
currentPermissionRequest.deny();
|
|
146
|
-
currentPermissionRequest = null;
|
|
147
|
-
}
|
|
148
|
-
if (call != null) {
|
|
149
|
-
call.reject("Microphone permission is required");
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
private void grantCameraAndMicrophonePermission() {
|
|
155
|
-
if (currentPermissionRequest != null) {
|
|
156
|
-
currentPermissionRequest.grant(
|
|
157
|
-
new String[] {
|
|
158
|
-
PermissionRequest.RESOURCE_VIDEO_CAPTURE,
|
|
159
|
-
PermissionRequest.RESOURCE_AUDIO_CAPTURE,
|
|
160
|
-
}
|
|
161
|
-
);
|
|
162
|
-
currentPermissionRequest = null;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
public void handleCameraPermissionRequest(PermissionRequest request) {
|
|
167
|
-
this.currentPermissionRequest = request;
|
|
168
|
-
if (getPermissionState("camera") != PermissionState.GRANTED) {
|
|
169
|
-
requestPermissionForAlias("camera", null, "cameraPermissionCallback");
|
|
170
|
-
} else if (getPermissionState("microphone") != PermissionState.GRANTED) {
|
|
171
|
-
requestPermissionForAlias(
|
|
172
|
-
"microphone",
|
|
173
|
-
null,
|
|
174
|
-
"microphonePermissionCallback"
|
|
175
|
-
);
|
|
176
|
-
} else {
|
|
177
|
-
grantCameraAndMicrophonePermission();
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
@PermissionCallback
|
|
182
|
-
private void cameraPermissionCallback(PluginCall call) {
|
|
183
|
-
if (getPermissionState("camera") == PermissionState.GRANTED) {
|
|
184
|
-
if (getPermissionState("microphone") != PermissionState.GRANTED) {
|
|
185
|
-
requestPermissionForAlias(
|
|
186
|
-
"microphone",
|
|
187
|
-
null,
|
|
188
|
-
"microphonePermissionCallback"
|
|
189
|
-
);
|
|
190
|
-
} else {
|
|
191
|
-
grantCameraAndMicrophonePermission();
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
if (currentPermissionRequest != null) {
|
|
195
|
-
currentPermissionRequest.deny();
|
|
196
|
-
currentPermissionRequest = null;
|
|
197
|
-
}
|
|
53
|
+
public static final String CUSTOM_TAB_PACKAGE_NAME = "com.android.chrome"; // Change when in stable
|
|
54
|
+
private CustomTabsClient customTabsClient;
|
|
55
|
+
private CustomTabsSession currentSession;
|
|
56
|
+
private WebViewDialog webViewDialog = null;
|
|
57
|
+
private String currentUrl = "";
|
|
198
58
|
|
|
199
|
-
|
|
200
|
-
if (call != null) {
|
|
201
|
-
call.reject("Camera permission is required");
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
@PermissionCallback
|
|
207
|
-
private void cameraPermissionCallback() {
|
|
208
|
-
if (getPermissionState("camera") == PermissionState.GRANTED) {
|
|
209
|
-
grantCameraPermission();
|
|
210
|
-
} else {
|
|
211
|
-
if (currentPermissionRequest != null) {
|
|
212
|
-
currentPermissionRequest.deny();
|
|
213
|
-
currentPermissionRequest = null;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
private void grantCameraPermission() {
|
|
219
|
-
if (currentPermissionRequest != null) {
|
|
220
|
-
currentPermissionRequest.grant(
|
|
221
|
-
new String[] { PermissionRequest.RESOURCE_VIDEO_CAPTURE }
|
|
222
|
-
);
|
|
223
|
-
currentPermissionRequest = null;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
59
|
+
private PermissionRequest currentPermissionRequest;
|
|
226
60
|
|
|
227
|
-
|
|
228
|
-
@Override
|
|
229
|
-
public void onCustomTabsServiceConnected(
|
|
230
|
-
ComponentName name,
|
|
231
|
-
CustomTabsClient client
|
|
232
|
-
) {
|
|
233
|
-
customTabsClient = client;
|
|
234
|
-
}
|
|
61
|
+
private ActivityResultLauncher<Intent> fileChooserLauncher;
|
|
235
62
|
|
|
236
63
|
@Override
|
|
237
|
-
public void
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
public void requestCameraPermission(PluginCall call) {
|
|
244
|
-
if (getPermissionState("camera") != PermissionState.GRANTED) {
|
|
245
|
-
requestPermissionForAlias("camera", call, "cameraPermissionCallback");
|
|
246
|
-
} else {
|
|
247
|
-
call.resolve();
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
@PluginMethod
|
|
252
|
-
public void setUrl(PluginCall call) {
|
|
253
|
-
String url = call.getString("url");
|
|
254
|
-
if (url == null || TextUtils.isEmpty(url)) {
|
|
255
|
-
call.reject("Invalid URL");
|
|
256
|
-
return;
|
|
64
|
+
public void load() {
|
|
65
|
+
super.load();
|
|
66
|
+
fileChooserLauncher = getActivity().registerForActivityResult(
|
|
67
|
+
new ActivityResultContracts.StartActivityForResult(),
|
|
68
|
+
this::handleFileChooserResult
|
|
69
|
+
);
|
|
257
70
|
}
|
|
258
71
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
72
|
+
private void handleFileChooserResult(ActivityResult result) {
|
|
73
|
+
if (webViewDialog != null && webViewDialog.mFilePathCallback != null) {
|
|
74
|
+
Uri[] results = null;
|
|
75
|
+
Intent data = result.getData();
|
|
263
76
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
77
|
+
if (result.getResultCode() == Activity.RESULT_OK) {
|
|
78
|
+
// Handle camera capture result
|
|
79
|
+
if (webViewDialog.tempCameraUri != null && (data == null || data.getData() == null)) {
|
|
80
|
+
results = new Uri[] { webViewDialog.tempCameraUri };
|
|
81
|
+
}
|
|
82
|
+
// Handle regular file picker result
|
|
83
|
+
else if (data != null) {
|
|
84
|
+
if (data.getClipData() != null) {
|
|
85
|
+
// Handle multiple files
|
|
86
|
+
int count = data.getClipData().getItemCount();
|
|
87
|
+
results = new Uri[count];
|
|
88
|
+
for (int i = 0; i < count; i++) {
|
|
89
|
+
results[i] = data.getClipData().getItemAt(i).getUri();
|
|
90
|
+
}
|
|
91
|
+
} else if (data.getData() != null) {
|
|
92
|
+
// Handle single file
|
|
93
|
+
results = new Uri[] { data.getData() };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
280
96
|
}
|
|
281
|
-
|
|
97
|
+
|
|
98
|
+
// Send the result to WebView and clean up
|
|
99
|
+
webViewDialog.mFilePathCallback.onReceiveValue(results);
|
|
100
|
+
webViewDialog.mFilePathCallback = null;
|
|
101
|
+
webViewDialog.tempCameraUri = null;
|
|
282
102
|
}
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
@PluginMethod
|
|
287
|
-
public void open(PluginCall call) {
|
|
288
|
-
String url = call.getString("url");
|
|
289
|
-
if (url == null) {
|
|
290
|
-
call.reject("URL is required");
|
|
291
|
-
return;
|
|
292
103
|
}
|
|
293
104
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (url == null || TextUtils.isEmpty(url)) {
|
|
302
|
-
call.reject("Invalid URL");
|
|
303
|
-
}
|
|
304
|
-
currentUrl = url;
|
|
305
|
-
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(
|
|
306
|
-
getCustomTabsSession()
|
|
307
|
-
);
|
|
308
|
-
CustomTabsIntent tabsIntent = builder.build();
|
|
309
|
-
tabsIntent.intent.putExtra(
|
|
310
|
-
Intent.EXTRA_REFERRER,
|
|
311
|
-
Uri.parse(
|
|
312
|
-
Intent.URI_ANDROID_APP_SCHEME + "//" + getContext().getPackageName()
|
|
313
|
-
)
|
|
314
|
-
);
|
|
315
|
-
tabsIntent.intent.putExtra(
|
|
316
|
-
android.provider.Browser.EXTRA_HEADERS,
|
|
317
|
-
this.getHeaders(call)
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
if (preventDeeplink != false) {
|
|
321
|
-
String browserPackageName = "";
|
|
322
|
-
Intent browserIntent = new Intent(
|
|
323
|
-
Intent.ACTION_VIEW,
|
|
324
|
-
Uri.parse("http://")
|
|
325
|
-
);
|
|
326
|
-
ResolveInfo resolveInfo = getContext()
|
|
327
|
-
.getPackageManager()
|
|
328
|
-
.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
|
|
329
|
-
|
|
330
|
-
if (resolveInfo != null) {
|
|
331
|
-
browserPackageName = resolveInfo.activityInfo.packageName;
|
|
332
|
-
|
|
333
|
-
if (!browserPackageName.isEmpty()) {
|
|
334
|
-
tabsIntent.intent.setPackage(browserPackageName);
|
|
105
|
+
public void handleMicrophonePermissionRequest(PermissionRequest request) {
|
|
106
|
+
this.currentPermissionRequest = request;
|
|
107
|
+
if (getPermissionState("microphone") != PermissionState.GRANTED) {
|
|
108
|
+
requestPermissionForAlias("microphone", null, "microphonePermissionCallback");
|
|
109
|
+
} else {
|
|
110
|
+
grantMicrophonePermission();
|
|
335
111
|
}
|
|
336
|
-
}
|
|
337
112
|
}
|
|
338
113
|
|
|
339
|
-
|
|
340
|
-
|
|
114
|
+
private void grantMicrophonePermission() {
|
|
115
|
+
if (currentPermissionRequest != null) {
|
|
116
|
+
currentPermissionRequest.grant(new String[] { PermissionRequest.RESOURCE_AUDIO_CAPTURE });
|
|
117
|
+
currentPermissionRequest = null;
|
|
118
|
+
}
|
|
341
119
|
}
|
|
342
120
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
@PluginMethod
|
|
357
|
-
public void clearAllCookies(PluginCall call) {
|
|
358
|
-
CookieManager cookieManager = CookieManager.getInstance();
|
|
359
|
-
cookieManager.removeAllCookies(null);
|
|
360
|
-
cookieManager.flush();
|
|
361
|
-
call.resolve();
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
@PluginMethod
|
|
365
|
-
public void clearCookies(PluginCall call) {
|
|
366
|
-
String url = call.getString("url", currentUrl);
|
|
367
|
-
if (url == null || TextUtils.isEmpty(url)) {
|
|
368
|
-
call.reject("Invalid URL");
|
|
369
|
-
return;
|
|
121
|
+
@PermissionCallback
|
|
122
|
+
private void microphonePermissionCallback(PluginCall call) {
|
|
123
|
+
if (getPermissionState("microphone") == PermissionState.GRANTED) {
|
|
124
|
+
grantCameraAndMicrophonePermission();
|
|
125
|
+
} else {
|
|
126
|
+
if (currentPermissionRequest != null) {
|
|
127
|
+
currentPermissionRequest.deny();
|
|
128
|
+
currentPermissionRequest = null;
|
|
129
|
+
}
|
|
130
|
+
if (call != null) {
|
|
131
|
+
call.reject("Microphone permission is required");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
370
134
|
}
|
|
371
135
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
136
|
+
private void grantCameraAndMicrophonePermission() {
|
|
137
|
+
if (currentPermissionRequest != null) {
|
|
138
|
+
currentPermissionRequest.grant(
|
|
139
|
+
new String[] { PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_AUDIO_CAPTURE }
|
|
140
|
+
);
|
|
141
|
+
currentPermissionRequest = null;
|
|
142
|
+
}
|
|
377
143
|
}
|
|
378
144
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
145
|
+
public void handleCameraPermissionRequest(PermissionRequest request) {
|
|
146
|
+
this.currentPermissionRequest = request;
|
|
147
|
+
if (getPermissionState("camera") != PermissionState.GRANTED) {
|
|
148
|
+
requestPermissionForAlias("camera", null, "cameraPermissionCallback");
|
|
149
|
+
} else if (getPermissionState("microphone") != PermissionState.GRANTED) {
|
|
150
|
+
requestPermissionForAlias("microphone", null, "microphonePermissionCallback");
|
|
151
|
+
} else {
|
|
152
|
+
grantCameraAndMicrophonePermission();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
382
155
|
|
|
383
|
-
|
|
384
|
-
|
|
156
|
+
@PermissionCallback
|
|
157
|
+
private void cameraPermissionCallback(PluginCall call) {
|
|
158
|
+
if (getPermissionState("camera") == PermissionState.GRANTED) {
|
|
159
|
+
if (getPermissionState("microphone") != PermissionState.GRANTED) {
|
|
160
|
+
requestPermissionForAlias("microphone", null, "microphonePermissionCallback");
|
|
161
|
+
} else {
|
|
162
|
+
grantCameraAndMicrophonePermission();
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
if (currentPermissionRequest != null) {
|
|
166
|
+
currentPermissionRequest.deny();
|
|
167
|
+
currentPermissionRequest = null;
|
|
168
|
+
}
|
|
385
169
|
|
|
386
|
-
|
|
170
|
+
// Reject only if there's a call - could be null for WebViewDialog flow
|
|
171
|
+
if (call != null) {
|
|
172
|
+
call.reject("Camera permission is required");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
387
176
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
if (
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
177
|
+
@PermissionCallback
|
|
178
|
+
private void cameraPermissionCallback() {
|
|
179
|
+
if (getPermissionState("camera") == PermissionState.GRANTED) {
|
|
180
|
+
grantCameraPermission();
|
|
181
|
+
} else {
|
|
182
|
+
if (currentPermissionRequest != null) {
|
|
183
|
+
currentPermissionRequest.deny();
|
|
184
|
+
currentPermissionRequest = null;
|
|
185
|
+
}
|
|
394
186
|
}
|
|
395
|
-
}
|
|
396
187
|
}
|
|
397
188
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
cookieToRemove,
|
|
404
|
-
cookieToRemove,
|
|
405
|
-
url
|
|
406
|
-
)
|
|
407
|
-
);
|
|
189
|
+
private void grantCameraPermission() {
|
|
190
|
+
if (currentPermissionRequest != null) {
|
|
191
|
+
currentPermissionRequest.grant(new String[] { PermissionRequest.RESOURCE_VIDEO_CAPTURE });
|
|
192
|
+
currentPermissionRequest = null;
|
|
193
|
+
}
|
|
408
194
|
}
|
|
409
195
|
|
|
410
|
-
|
|
196
|
+
CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
|
|
197
|
+
@Override
|
|
198
|
+
public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
|
|
199
|
+
customTabsClient = client;
|
|
200
|
+
}
|
|
411
201
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
@Override
|
|
416
|
-
public void run() {
|
|
417
|
-
try {
|
|
418
|
-
if (webViewDialog != null) {
|
|
419
|
-
webViewDialog.executeScript(scriptToRun.toString());
|
|
420
|
-
call.resolve();
|
|
421
|
-
} else {
|
|
422
|
-
call.reject("WebView is not initialized");
|
|
423
|
-
}
|
|
424
|
-
} catch (Exception e) {
|
|
425
|
-
Log.e(
|
|
426
|
-
"InAppBrowser",
|
|
427
|
-
"Error clearing cookies: " + e.getMessage()
|
|
428
|
-
);
|
|
429
|
-
call.reject("Failed to clear cookies: " + e.getMessage());
|
|
430
|
-
}
|
|
431
|
-
}
|
|
202
|
+
@Override
|
|
203
|
+
public void onServiceDisconnected(ComponentName name) {
|
|
204
|
+
customTabsClient = null;
|
|
432
205
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
CookieManager cookieManager = CookieManager.getInstance();
|
|
444
|
-
String cookieString = cookieManager.getCookie(url);
|
|
445
|
-
JSObject result = new JSObject();
|
|
446
|
-
if (cookieString != null) {
|
|
447
|
-
String[] cookiePairs = cookieString.split("; ");
|
|
448
|
-
for (String cookie : cookiePairs) {
|
|
449
|
-
String[] parts = cookie.split("=", 2);
|
|
450
|
-
if (parts.length == 2) {
|
|
451
|
-
result.put(parts[0], parts[1]);
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
@PluginMethod
|
|
209
|
+
public void requestCameraPermission(PluginCall call) {
|
|
210
|
+
if (getPermissionState("camera") != PermissionState.GRANTED) {
|
|
211
|
+
requestPermissionForAlias("camera", call, "cameraPermissionCallback");
|
|
212
|
+
} else {
|
|
213
|
+
call.resolve();
|
|
452
214
|
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
call.resolve(result);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
@PluginMethod
|
|
459
|
-
public void openWebView(PluginCall call) {
|
|
460
|
-
String url = call.getString("url");
|
|
461
|
-
if (url == null || TextUtils.isEmpty(url)) {
|
|
462
|
-
call.reject("Invalid URL");
|
|
463
|
-
}
|
|
464
|
-
currentUrl = url;
|
|
465
|
-
final Options options = new Options();
|
|
466
|
-
options.setUrl(url);
|
|
467
|
-
options.setHeaders(call.getObject("headers"));
|
|
468
|
-
options.setCredentials(call.getObject("credentials"));
|
|
469
|
-
options.setShowReloadButton(
|
|
470
|
-
Boolean.TRUE.equals(call.getBoolean("showReloadButton", false))
|
|
471
|
-
);
|
|
472
|
-
options.setVisibleTitle(
|
|
473
|
-
Boolean.TRUE.equals(call.getBoolean("visibleTitle", true))
|
|
474
|
-
);
|
|
475
|
-
if (Boolean.TRUE.equals(options.getVisibleTitle())) {
|
|
476
|
-
options.setTitle(call.getString("title", "New Window"));
|
|
477
|
-
} else {
|
|
478
|
-
options.setTitle(call.getString("title", ""));
|
|
479
|
-
}
|
|
480
|
-
options.setToolbarColor(call.getString("toolbarColor", "#ffffff"));
|
|
481
|
-
options.setBackgroundColor(call.getString("backgroundColor", "white"));
|
|
482
|
-
options.setToolbarTextColor(call.getString("toolbarTextColor"));
|
|
483
|
-
options.setArrow(Boolean.TRUE.equals(call.getBoolean("showArrow", false)));
|
|
484
|
-
options.setIgnoreUntrustedSSLError(
|
|
485
|
-
Boolean.TRUE.equals(call.getBoolean("ignoreUntrustedSSLError", false))
|
|
486
|
-
);
|
|
487
|
-
|
|
488
|
-
// Set text zoom if specified in options (default is 100)
|
|
489
|
-
Integer textZoom = call.getInt("textZoom");
|
|
490
|
-
if (textZoom != null) {
|
|
491
|
-
options.setTextZoom(textZoom);
|
|
492
215
|
}
|
|
493
216
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
217
|
+
@PluginMethod
|
|
218
|
+
public void setUrl(PluginCall call) {
|
|
219
|
+
String url = call.getString("url");
|
|
220
|
+
if (url == null || TextUtils.isEmpty(url)) {
|
|
221
|
+
call.reject("Invalid URL");
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (webViewDialog == null) {
|
|
226
|
+
call.reject("WebView is not initialized");
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
currentUrl = url;
|
|
231
|
+
this.getActivity().runOnUiThread(
|
|
232
|
+
new Runnable() {
|
|
233
|
+
@Override
|
|
234
|
+
public void run() {
|
|
235
|
+
try {
|
|
236
|
+
if (webViewDialog != null) {
|
|
237
|
+
webViewDialog.setUrl(url);
|
|
238
|
+
call.resolve();
|
|
239
|
+
} else {
|
|
240
|
+
call.reject("WebView is not initialized");
|
|
241
|
+
}
|
|
242
|
+
} catch (Exception e) {
|
|
243
|
+
Log.e("InAppBrowser", "Error setting URL: " + e.getMessage());
|
|
244
|
+
call.reject("Failed to set URL: " + e.getMessage());
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
502
248
|
);
|
|
503
|
-
}
|
|
504
249
|
}
|
|
505
250
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if (androidObj != null) {
|
|
514
|
-
String iconType = androidObj.getString("iconType", "asset");
|
|
515
|
-
String icon = androidObj.getString("icon", "");
|
|
516
|
-
Log.d(
|
|
517
|
-
"InAppBrowser",
|
|
518
|
-
"ButtonNearDone config - iconType: " +
|
|
519
|
-
iconType +
|
|
520
|
-
", icon: " +
|
|
521
|
-
icon
|
|
522
|
-
);
|
|
251
|
+
@PluginMethod
|
|
252
|
+
public void open(PluginCall call) {
|
|
253
|
+
String url = call.getString("url");
|
|
254
|
+
if (url == null) {
|
|
255
|
+
call.reject("URL is required");
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
523
258
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
259
|
+
// get the deeplink prevention, if provided
|
|
260
|
+
Boolean preventDeeplink = call.getBoolean("preventDeeplink", false);
|
|
261
|
+
Boolean isPresentAfterPageLoad = call.getBoolean("isPresentAfterPageLoad", false);
|
|
262
|
+
|
|
263
|
+
if (url == null || TextUtils.isEmpty(url)) {
|
|
264
|
+
call.reject("Invalid URL");
|
|
265
|
+
}
|
|
266
|
+
currentUrl = url;
|
|
267
|
+
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(getCustomTabsSession());
|
|
268
|
+
CustomTabsIntent tabsIntent = builder.build();
|
|
269
|
+
tabsIntent.intent.putExtra(Intent.EXTRA_REFERRER, Uri.parse(Intent.URI_ANDROID_APP_SCHEME + "//" + getContext().getPackageName()));
|
|
270
|
+
tabsIntent.intent.putExtra(android.provider.Browser.EXTRA_HEADERS, this.getHeaders(call));
|
|
271
|
+
|
|
272
|
+
if (preventDeeplink != false) {
|
|
273
|
+
String browserPackageName = "";
|
|
274
|
+
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"));
|
|
275
|
+
ResolveInfo resolveInfo = getContext().getPackageManager().resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
|
|
276
|
+
|
|
277
|
+
if (resolveInfo != null) {
|
|
278
|
+
browserPackageName = resolveInfo.activityInfo.packageName;
|
|
279
|
+
|
|
280
|
+
if (!browserPackageName.isEmpty()) {
|
|
281
|
+
tabsIntent.intent.setPackage(browserPackageName);
|
|
540
282
|
}
|
|
541
|
-
} else {
|
|
542
|
-
Log.d(
|
|
543
|
-
"InAppBrowser",
|
|
544
|
-
"Vector resource found with ID: " + resourceId
|
|
545
|
-
);
|
|
546
|
-
}
|
|
547
283
|
}
|
|
548
|
-
|
|
284
|
+
}
|
|
549
285
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
Options.ButtonNearDone.generateFromPluginCall(
|
|
553
|
-
call,
|
|
554
|
-
getContext().getAssets()
|
|
555
|
-
);
|
|
556
|
-
options.setButtonNearDone(buttonNearDone);
|
|
557
|
-
} catch (Exception e) {
|
|
558
|
-
Log.e(
|
|
559
|
-
"InAppBrowser",
|
|
560
|
-
"Error setting buttonNearDone: " + e.getMessage(),
|
|
561
|
-
e
|
|
562
|
-
);
|
|
286
|
+
if (isPresentAfterPageLoad) {
|
|
287
|
+
tabsIntent.intent.putExtra("isPresentAfterPageLoad", true);
|
|
563
288
|
}
|
|
564
|
-
}
|
|
565
|
-
} catch (Exception e) {
|
|
566
|
-
Log.e(
|
|
567
|
-
"InAppBrowser",
|
|
568
|
-
"Error processing buttonNearDone: " + e.getMessage(),
|
|
569
|
-
e
|
|
570
|
-
);
|
|
571
|
-
}
|
|
572
289
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
options.setToolbarType(call.getString("toolbarType", ""));
|
|
577
|
-
options.setPreventDeeplink(
|
|
578
|
-
Boolean.TRUE.equals(call.getBoolean("preventDeeplink", false))
|
|
579
|
-
);
|
|
580
|
-
|
|
581
|
-
// Validate preShowScript requires isPresentAfterPageLoad
|
|
582
|
-
if (
|
|
583
|
-
call.getData().has("preShowScript") &&
|
|
584
|
-
!Boolean.TRUE.equals(call.getBoolean("isPresentAfterPageLoad", false))
|
|
585
|
-
) {
|
|
586
|
-
call.reject("preShowScript requires isPresentAfterPageLoad to be true");
|
|
587
|
-
return;
|
|
290
|
+
tabsIntent.launchUrl(getContext(), Uri.parse(url));
|
|
291
|
+
|
|
292
|
+
call.resolve();
|
|
588
293
|
}
|
|
589
294
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
call.
|
|
596
|
-
);
|
|
597
|
-
options.setCloseModalOk(call.getString("closeModalOk", "Ok"));
|
|
598
|
-
options.setCloseModalCancel(call.getString("closeModalCancel", "Cancel"));
|
|
599
|
-
} else {
|
|
600
|
-
// Reject if closeModal is false but closeModal options are provided
|
|
601
|
-
if (
|
|
602
|
-
call.getData().has("closeModalTitle") ||
|
|
603
|
-
call.getData().has("closeModalDescription") ||
|
|
604
|
-
call.getData().has("closeModalOk") ||
|
|
605
|
-
call.getData().has("closeModalCancel")
|
|
606
|
-
) {
|
|
607
|
-
call.reject("closeModal options require closeModal to be true");
|
|
608
|
-
return;
|
|
609
|
-
}
|
|
610
|
-
options.setCloseModal(false);
|
|
295
|
+
@PluginMethod
|
|
296
|
+
public void clearCache(PluginCall call) {
|
|
297
|
+
CookieManager cookieManager = CookieManager.getInstance();
|
|
298
|
+
cookieManager.removeAllCookies(null);
|
|
299
|
+
cookieManager.flush();
|
|
300
|
+
call.resolve();
|
|
611
301
|
}
|
|
612
302
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
return;
|
|
303
|
+
@PluginMethod
|
|
304
|
+
public void clearAllCookies(PluginCall call) {
|
|
305
|
+
CookieManager cookieManager = CookieManager.getInstance();
|
|
306
|
+
cookieManager.removeAllCookies(null);
|
|
307
|
+
cookieManager.flush();
|
|
308
|
+
call.resolve();
|
|
620
309
|
}
|
|
621
310
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
311
|
+
@PluginMethod
|
|
312
|
+
public void clearCookies(PluginCall call) {
|
|
313
|
+
String url = call.getString("url", currentUrl);
|
|
314
|
+
if (url == null || TextUtils.isEmpty(url)) {
|
|
315
|
+
call.reject("Invalid URL");
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
Uri uri = Uri.parse(url);
|
|
320
|
+
String host = uri.getHost();
|
|
321
|
+
if (host == null || TextUtils.isEmpty(host)) {
|
|
322
|
+
call.reject("Invalid URL (Host is null)");
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
CookieManager cookieManager = CookieManager.getInstance();
|
|
327
|
+
String cookieString = cookieManager.getCookie(url);
|
|
328
|
+
ArrayList<String> cookiesToRemove = new ArrayList<>();
|
|
329
|
+
|
|
330
|
+
if (cookieString != null) {
|
|
331
|
+
String[] cookies = cookieString.split("; ");
|
|
332
|
+
|
|
333
|
+
String domain = uri.getHost();
|
|
334
|
+
|
|
335
|
+
for (String cookie : cookies) {
|
|
336
|
+
String[] parts = cookie.split("=");
|
|
337
|
+
if (parts.length > 0) {
|
|
338
|
+
cookiesToRemove.add(parts[0].trim());
|
|
339
|
+
CookieManager.getInstance().setCookie(url, String.format("%s=del;", parts[0].trim()));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
StringBuilder scriptToRun = new StringBuilder();
|
|
345
|
+
for (String cookieToRemove : cookiesToRemove) {
|
|
346
|
+
scriptToRun.append(
|
|
347
|
+
String.format("window.cookieStore.delete('%s', {name: '%s', domain: '%s'});", cookieToRemove, cookieToRemove, url)
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
Log.i("DelCookies", String.format("Script to run:\n%s", scriptToRun));
|
|
352
|
+
|
|
353
|
+
this.getActivity().runOnUiThread(
|
|
354
|
+
new Runnable() {
|
|
355
|
+
@Override
|
|
356
|
+
public void run() {
|
|
357
|
+
try {
|
|
358
|
+
if (webViewDialog != null) {
|
|
359
|
+
webViewDialog.executeScript(scriptToRun.toString());
|
|
360
|
+
call.resolve();
|
|
361
|
+
} else {
|
|
362
|
+
call.reject("WebView is not initialized");
|
|
363
|
+
}
|
|
364
|
+
} catch (Exception e) {
|
|
365
|
+
Log.e("InAppBrowser", "Error clearing cookies: " + e.getMessage());
|
|
366
|
+
call.reject("Failed to clear cookies: " + e.getMessage());
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
632
370
|
);
|
|
633
|
-
return;
|
|
634
|
-
}
|
|
635
371
|
}
|
|
636
372
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
call.
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
Boolean.TRUE.equals(
|
|
644
|
-
call.getBoolean("disableGoBackOnNativeApplication", false)
|
|
645
|
-
)
|
|
646
|
-
);
|
|
647
|
-
options.setPresentAfterPageLoad(
|
|
648
|
-
Boolean.TRUE.equals(call.getBoolean("isPresentAfterPageLoad", false))
|
|
649
|
-
);
|
|
650
|
-
options.setPluginCall(call);
|
|
651
|
-
|
|
652
|
-
// Set Material Design picker option
|
|
653
|
-
options.setMaterialPicker(
|
|
654
|
-
Boolean.TRUE.equals(call.getBoolean("materialPicker", false))
|
|
655
|
-
);
|
|
656
|
-
|
|
657
|
-
// Set enabledSafeBottomMargin option
|
|
658
|
-
options.setEnabledSafeMargin(
|
|
659
|
-
Boolean.TRUE.equals(call.getBoolean("enabledSafeBottomMargin", false))
|
|
660
|
-
);
|
|
661
|
-
|
|
662
|
-
// Use system top inset for WebView margin when explicitly enabled
|
|
663
|
-
options.setUseTopInset(
|
|
664
|
-
Boolean.TRUE.equals(call.getBoolean("useTopInset", false))
|
|
665
|
-
);
|
|
666
|
-
|
|
667
|
-
// options.getToolbarItemTypes().add(ToolbarItemType.RELOAD); TODO: fix this
|
|
668
|
-
options.setCallbacks(
|
|
669
|
-
new WebViewCallbacks() {
|
|
670
|
-
@Override
|
|
671
|
-
public void urlChangeEvent(String url) {
|
|
672
|
-
notifyListeners("urlChangeEvent", new JSObject().put("url", url));
|
|
373
|
+
@PluginMethod
|
|
374
|
+
public void getCookies(PluginCall call) {
|
|
375
|
+
String url = call.getString("url");
|
|
376
|
+
if (url == null || TextUtils.isEmpty(url)) {
|
|
377
|
+
call.reject("Invalid URL");
|
|
378
|
+
return;
|
|
673
379
|
}
|
|
380
|
+
CookieManager cookieManager = CookieManager.getInstance();
|
|
381
|
+
String cookieString = cookieManager.getCookie(url);
|
|
382
|
+
JSObject result = new JSObject();
|
|
383
|
+
if (cookieString != null) {
|
|
384
|
+
String[] cookiePairs = cookieString.split("; ");
|
|
385
|
+
for (String cookie : cookiePairs) {
|
|
386
|
+
String[] parts = cookie.split("=", 2);
|
|
387
|
+
if (parts.length == 2) {
|
|
388
|
+
result.put(parts[0], parts[1]);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
call.resolve(result);
|
|
393
|
+
}
|
|
674
394
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
395
|
+
@PluginMethod
|
|
396
|
+
public void openWebView(PluginCall call) {
|
|
397
|
+
String url = call.getString("url");
|
|
398
|
+
if (url == null || TextUtils.isEmpty(url)) {
|
|
399
|
+
call.reject("Invalid URL");
|
|
400
|
+
}
|
|
401
|
+
currentUrl = url;
|
|
402
|
+
final Options options = new Options();
|
|
403
|
+
options.setUrl(url);
|
|
404
|
+
options.setHeaders(call.getObject("headers"));
|
|
405
|
+
options.setCredentials(call.getObject("credentials"));
|
|
406
|
+
options.setShowReloadButton(Boolean.TRUE.equals(call.getBoolean("showReloadButton", false)));
|
|
407
|
+
options.setVisibleTitle(Boolean.TRUE.equals(call.getBoolean("visibleTitle", true)));
|
|
408
|
+
if (Boolean.TRUE.equals(options.getVisibleTitle())) {
|
|
409
|
+
options.setTitle(call.getString("title", "New Window"));
|
|
410
|
+
} else {
|
|
411
|
+
options.setTitle(call.getString("title", ""));
|
|
412
|
+
}
|
|
413
|
+
options.setToolbarColor(call.getString("toolbarColor", "#ffffff"));
|
|
414
|
+
options.setBackgroundColor(call.getString("backgroundColor", "white"));
|
|
415
|
+
options.setToolbarTextColor(call.getString("toolbarTextColor"));
|
|
416
|
+
options.setArrow(Boolean.TRUE.equals(call.getBoolean("showArrow", false)));
|
|
417
|
+
options.setIgnoreUntrustedSSLError(Boolean.TRUE.equals(call.getBoolean("ignoreUntrustedSSLError", false)));
|
|
418
|
+
|
|
419
|
+
// Set text zoom if specified in options (default is 100)
|
|
420
|
+
Integer textZoom = call.getInt("textZoom");
|
|
421
|
+
if (textZoom != null) {
|
|
422
|
+
options.setTextZoom(textZoom);
|
|
678
423
|
}
|
|
679
424
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
425
|
+
String proxyRequestsStr = call.getString("proxyRequests");
|
|
426
|
+
if (proxyRequestsStr != null) {
|
|
427
|
+
try {
|
|
428
|
+
options.setProxyRequestsPattern(Pattern.compile(proxyRequestsStr));
|
|
429
|
+
} catch (PatternSyntaxException e) {
|
|
430
|
+
Log.e("WebViewDialog", String.format("Pattern '%s' is not a valid pattern", proxyRequestsStr));
|
|
431
|
+
}
|
|
683
432
|
}
|
|
684
433
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
434
|
+
try {
|
|
435
|
+
// Try to set buttonNearDone if present, with better error handling
|
|
436
|
+
JSObject buttonNearDoneObj = call.getObject("buttonNearDone");
|
|
437
|
+
if (buttonNearDoneObj != null) {
|
|
438
|
+
try {
|
|
439
|
+
// Provide better debugging for buttonNearDone
|
|
440
|
+
JSObject androidObj = buttonNearDoneObj.getJSObject("android");
|
|
441
|
+
if (androidObj != null) {
|
|
442
|
+
String iconType = androidObj.getString("iconType", "asset");
|
|
443
|
+
String icon = androidObj.getString("icon", "");
|
|
444
|
+
Log.d("InAppBrowser", "ButtonNearDone config - iconType: " + iconType + ", icon: " + icon);
|
|
445
|
+
|
|
446
|
+
// For vector type, verify if resource exists
|
|
447
|
+
if ("vector".equals(iconType)) {
|
|
448
|
+
int resourceId = getContext().getResources().getIdentifier(icon, "drawable", getContext().getPackageName());
|
|
449
|
+
if (resourceId == 0) {
|
|
450
|
+
Log.e("InAppBrowser", "Vector resource not found: " + icon);
|
|
451
|
+
// List available drawable resources to help debugging
|
|
452
|
+
try {
|
|
453
|
+
final StringBuilder availableResources = getStringBuilder();
|
|
454
|
+
Log.d("InAppBrowser", availableResources.toString());
|
|
455
|
+
} catch (Exception e) {
|
|
456
|
+
Log.e("InAppBrowser", "Error listing resources: " + e.getMessage());
|
|
457
|
+
}
|
|
458
|
+
} else {
|
|
459
|
+
Log.d("InAppBrowser", "Vector resource found with ID: " + resourceId);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Try to create the ButtonNearDone object
|
|
465
|
+
Options.ButtonNearDone buttonNearDone = Options.ButtonNearDone.generateFromPluginCall(call, getContext().getAssets());
|
|
466
|
+
options.setButtonNearDone(buttonNearDone);
|
|
467
|
+
} catch (Exception e) {
|
|
468
|
+
Log.e("InAppBrowser", "Error setting buttonNearDone: " + e.getMessage(), e);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
} catch (Exception e) {
|
|
472
|
+
Log.e("InAppBrowser", "Error processing buttonNearDone: " + e.getMessage(), e);
|
|
688
473
|
}
|
|
689
474
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
475
|
+
options.setShareDisclaimer(call.getObject("shareDisclaimer", null));
|
|
476
|
+
options.setPreShowScript(call.getString("preShowScript", null));
|
|
477
|
+
options.setShareSubject(call.getString("shareSubject", null));
|
|
478
|
+
options.setToolbarType(call.getString("toolbarType", ""));
|
|
479
|
+
options.setPreventDeeplink(Boolean.TRUE.equals(call.getBoolean("preventDeeplink", false)));
|
|
480
|
+
|
|
481
|
+
// Validate preShowScript requires isPresentAfterPageLoad
|
|
482
|
+
if (call.getData().has("preShowScript") && !Boolean.TRUE.equals(call.getBoolean("isPresentAfterPageLoad", false))) {
|
|
483
|
+
call.reject("preShowScript requires isPresentAfterPageLoad to be true");
|
|
484
|
+
return;
|
|
693
485
|
}
|
|
694
486
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
487
|
+
// Validate closeModal options
|
|
488
|
+
if (Boolean.TRUE.equals(call.getBoolean("closeModal", false))) {
|
|
489
|
+
options.setCloseModal(true);
|
|
490
|
+
options.setCloseModalTitle(call.getString("closeModalTitle", "Close"));
|
|
491
|
+
options.setCloseModalDescription(call.getString("closeModalDescription", "Are you sure ?"));
|
|
492
|
+
options.setCloseModalOk(call.getString("closeModalOk", "Ok"));
|
|
493
|
+
options.setCloseModalCancel(call.getString("closeModalCancel", "Cancel"));
|
|
494
|
+
} else {
|
|
495
|
+
// Reject if closeModal is false but closeModal options are provided
|
|
496
|
+
if (
|
|
497
|
+
call.getData().has("closeModalTitle") ||
|
|
498
|
+
call.getData().has("closeModalDescription") ||
|
|
499
|
+
call.getData().has("closeModalOk") ||
|
|
500
|
+
call.getData().has("closeModalCancel")
|
|
501
|
+
) {
|
|
502
|
+
call.reject("closeModal options require closeModal to be true");
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
options.setCloseModal(false);
|
|
698
506
|
}
|
|
699
507
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
Iterator<String> keys = jsonMessage.keys();
|
|
717
|
-
while (keys.hasNext()) {
|
|
718
|
-
String key = keys.next();
|
|
719
|
-
jsObject.put(key, jsonMessage.get(key));
|
|
508
|
+
// Validate shareDisclaimer requires shareSubject
|
|
509
|
+
if (call.getData().has("shareDisclaimer") && !call.getData().has("shareSubject")) {
|
|
510
|
+
call.reject("shareDisclaimer requires shareSubject to be provided");
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Validate buttonNearDone compatibility with toolbar type
|
|
515
|
+
if (call.getData().has("buttonNearDone")) {
|
|
516
|
+
String toolbarType = options.getToolbarType();
|
|
517
|
+
if (
|
|
518
|
+
TextUtils.equals(toolbarType, "activity") ||
|
|
519
|
+
TextUtils.equals(toolbarType, "navigation") ||
|
|
520
|
+
TextUtils.equals(toolbarType, "blank")
|
|
521
|
+
) {
|
|
522
|
+
call.reject("buttonNearDone is not compatible with toolbarType: " + toolbarType);
|
|
523
|
+
return;
|
|
720
524
|
}
|
|
525
|
+
}
|
|
721
526
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
527
|
+
options.setActiveNativeNavigationForWebview(Boolean.TRUE.equals(call.getBoolean("activeNativeNavigationForWebview", false)));
|
|
528
|
+
options.setDisableGoBackOnNativeApplication(Boolean.TRUE.equals(call.getBoolean("disableGoBackOnNativeApplication", false)));
|
|
529
|
+
options.setPresentAfterPageLoad(Boolean.TRUE.equals(call.getBoolean("isPresentAfterPageLoad", false)));
|
|
530
|
+
options.setPluginCall(call);
|
|
531
|
+
|
|
532
|
+
// Set Material Design picker option
|
|
533
|
+
options.setMaterialPicker(Boolean.TRUE.equals(call.getBoolean("materialPicker", false)));
|
|
534
|
+
|
|
535
|
+
// Set enabledSafeBottomMargin option
|
|
536
|
+
options.setEnabledSafeMargin(Boolean.TRUE.equals(call.getBoolean("enabledSafeBottomMargin", false)));
|
|
537
|
+
|
|
538
|
+
// Use system top inset for WebView margin when explicitly enabled
|
|
539
|
+
options.setUseTopInset(Boolean.TRUE.equals(call.getBoolean("useTopInset", false)));
|
|
729
540
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
541
|
+
// options.getToolbarItemTypes().add(ToolbarItemType.RELOAD); TODO: fix this
|
|
542
|
+
options.setCallbacks(
|
|
543
|
+
new WebViewCallbacks() {
|
|
544
|
+
@Override
|
|
545
|
+
public void urlChangeEvent(String url) {
|
|
546
|
+
notifyListeners("urlChangeEvent", new JSObject().put("url", url));
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
@Override
|
|
550
|
+
public void closeEvent(String url) {
|
|
551
|
+
notifyListeners("closeEvent", new JSObject().put("url", url));
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
@Override
|
|
555
|
+
public void pageLoaded() {
|
|
556
|
+
notifyListeners("browserPageLoaded", new JSObject());
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
@Override
|
|
560
|
+
public void pageLoadError() {
|
|
561
|
+
notifyListeners("pageLoadError", new JSObject());
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
@Override
|
|
565
|
+
public void buttonNearDoneClicked() {
|
|
566
|
+
notifyListeners("buttonNearDoneClick", new JSObject());
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
@Override
|
|
570
|
+
public void confirmBtnClicked(String url) {
|
|
571
|
+
notifyListeners("confirmBtnClicked", new JSObject().put("url", url));
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
@Override
|
|
575
|
+
public void javascriptCallback(String message) {
|
|
576
|
+
// Handle the message received from JavaScript
|
|
577
|
+
Log.d("WebViewDialog", "Received message from JavaScript: " + message);
|
|
578
|
+
// Process the message as needed
|
|
579
|
+
try {
|
|
580
|
+
// Parse the received message as a JSON object
|
|
581
|
+
JSONObject jsonMessage = new JSONObject(message);
|
|
582
|
+
|
|
583
|
+
// Create a new JSObject to send to the Capacitor plugin
|
|
584
|
+
JSObject jsObject = new JSObject();
|
|
585
|
+
|
|
586
|
+
// Iterate through the keys in the JSON object and add them to the JSObject
|
|
587
|
+
Iterator<String> keys = jsonMessage.keys();
|
|
588
|
+
while (keys.hasNext()) {
|
|
589
|
+
String key = keys.next();
|
|
590
|
+
jsObject.put(key, jsonMessage.get(key));
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// Notify listeners with the parsed message
|
|
594
|
+
notifyListeners("messageFromWebview", jsObject);
|
|
595
|
+
} catch (JSONException e) {
|
|
596
|
+
Log.e("WebViewDialog", "Error parsing JSON message: " + e.getMessage());
|
|
597
|
+
|
|
598
|
+
// If JSON parsing fails, send the raw message as a string
|
|
599
|
+
JSObject jsObject = new JSObject();
|
|
600
|
+
jsObject.put("rawMessage", message);
|
|
601
|
+
notifyListeners("messageFromWebview", jsObject);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
JSArray jsAuthorizedLinks = call.getArray("authorizedAppLinks");
|
|
608
|
+
if (jsAuthorizedLinks != null && jsAuthorizedLinks.length() > 0) {
|
|
609
|
+
List<String> authorizedLinks = new ArrayList<>();
|
|
610
|
+
for (int i = 0; i < jsAuthorizedLinks.length(); i++) {
|
|
611
|
+
try {
|
|
612
|
+
String link = jsAuthorizedLinks.getString(i);
|
|
613
|
+
if (link != null && !link.trim().isEmpty()) {
|
|
614
|
+
authorizedLinks.add(link);
|
|
615
|
+
}
|
|
616
|
+
} catch (Exception e) {
|
|
617
|
+
Log.w("InAppBrowserPlugin", "Error reading authorized app link at index " + i, e);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
Log.d("InAppBrowserPlugin", "Parsed authorized app links: " + authorizedLinks);
|
|
621
|
+
options.setAuthorizedAppLinks(authorizedLinks);
|
|
622
|
+
} else {
|
|
623
|
+
Log.d("InAppBrowserPlugin", "No authorized app links provided.");
|
|
735
624
|
}
|
|
736
|
-
}
|
|
737
|
-
);
|
|
738
625
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
626
|
+
JSArray blockedHostsRaw = call.getArray("blockedHosts");
|
|
627
|
+
if (blockedHostsRaw != null && blockedHostsRaw.length() > 0) {
|
|
628
|
+
List<String> blockedHosts = new ArrayList<>();
|
|
629
|
+
for (int i = 0; i < blockedHostsRaw.length(); i++) {
|
|
630
|
+
try {
|
|
631
|
+
String host = blockedHostsRaw.getString(i);
|
|
632
|
+
if (host != null && !host.trim().isEmpty()) {
|
|
633
|
+
blockedHosts.add(host);
|
|
634
|
+
}
|
|
635
|
+
} catch (Exception e) {
|
|
636
|
+
Log.w("InAppBrowserPlugin", "Error reading blocked host at index " + i, e);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
Log.d("InAppBrowserPlugin", "Parsed blocked hosts: " + blockedHosts);
|
|
640
|
+
options.setBlockedHosts(blockedHosts);
|
|
641
|
+
} else {
|
|
642
|
+
Log.d("InAppBrowserPlugin", "No blocked hosts provided.");
|
|
754
643
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
"
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
644
|
+
|
|
645
|
+
// Set Google Pay support option
|
|
646
|
+
options.setEnableGooglePaySupport(Boolean.TRUE.equals(call.getBoolean("enableGooglePaySupport", false)));
|
|
647
|
+
|
|
648
|
+
this.getActivity().runOnUiThread(
|
|
649
|
+
new Runnable() {
|
|
650
|
+
@Override
|
|
651
|
+
public void run() {
|
|
652
|
+
webViewDialog = new WebViewDialog(
|
|
653
|
+
getContext(),
|
|
654
|
+
android.R.style.Theme_NoTitleBar,
|
|
655
|
+
options,
|
|
656
|
+
InAppBrowserPlugin.this,
|
|
657
|
+
getBridge().getWebView()
|
|
658
|
+
);
|
|
659
|
+
webViewDialog.activity = InAppBrowserPlugin.this.getActivity();
|
|
660
|
+
webViewDialog.presentWebView();
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
);
|
|
763
664
|
}
|
|
764
665
|
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
if (host != null && !host.trim().isEmpty()) {
|
|
772
|
-
blockedHosts.add(host);
|
|
773
|
-
}
|
|
774
|
-
} catch (Exception e) {
|
|
775
|
-
Log.w(
|
|
776
|
-
"InAppBrowserPlugin",
|
|
777
|
-
"Error reading blocked host at index " + i,
|
|
778
|
-
e
|
|
779
|
-
);
|
|
666
|
+
@NonNull
|
|
667
|
+
private static StringBuilder getStringBuilder() {
|
|
668
|
+
Field[] drawables = R.drawable.class.getFields();
|
|
669
|
+
StringBuilder availableResources = new StringBuilder("Available resources: ");
|
|
670
|
+
for (int i = 0; i < Math.min(10, drawables.length); i++) {
|
|
671
|
+
availableResources.append(drawables[i].getName()).append(", ");
|
|
780
672
|
}
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
Log.d("InAppBrowserPlugin", "No blocked hosts provided.");
|
|
673
|
+
if (drawables.length > 10) {
|
|
674
|
+
availableResources.append("... (").append(drawables.length - 10).append(" more)");
|
|
675
|
+
}
|
|
676
|
+
return availableResources;
|
|
786
677
|
}
|
|
787
678
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
getContext(),
|
|
800
|
-
android.R.style.Theme_NoTitleBar,
|
|
801
|
-
options,
|
|
802
|
-
InAppBrowserPlugin.this,
|
|
803
|
-
getBridge().getWebView()
|
|
804
|
-
);
|
|
805
|
-
webViewDialog.activity = InAppBrowserPlugin.this.getActivity();
|
|
806
|
-
webViewDialog.presentWebView();
|
|
807
|
-
}
|
|
679
|
+
@PluginMethod
|
|
680
|
+
public void postMessage(PluginCall call) {
|
|
681
|
+
if (webViewDialog == null) {
|
|
682
|
+
call.reject("WebView is not initialized");
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
JSObject eventData = call.getObject("detail");
|
|
686
|
+
// Log event data
|
|
687
|
+
if (eventData == null) {
|
|
688
|
+
call.reject("No event data provided");
|
|
689
|
+
return;
|
|
808
690
|
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
691
|
+
|
|
692
|
+
Log.d("InAppBrowserPlugin", "Event data: " + eventData.toString());
|
|
693
|
+
this.getActivity().runOnUiThread(
|
|
694
|
+
new Runnable() {
|
|
695
|
+
@Override
|
|
696
|
+
public void run() {
|
|
697
|
+
if (webViewDialog != null) {
|
|
698
|
+
webViewDialog.postMessageToJS(eventData);
|
|
699
|
+
call.resolve();
|
|
700
|
+
} else {
|
|
701
|
+
call.reject("WebView is not initialized");
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
);
|
|
820
706
|
}
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
.
|
|
825
|
-
.
|
|
707
|
+
|
|
708
|
+
@PluginMethod
|
|
709
|
+
public void executeScript(PluginCall call) {
|
|
710
|
+
String script = call.getString("code");
|
|
711
|
+
if (script == null || script.trim().isEmpty()) {
|
|
712
|
+
call.reject("Script is required");
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
if (webViewDialog == null) {
|
|
717
|
+
call.reject("WebView is not initialized");
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
this.getActivity().runOnUiThread(
|
|
722
|
+
new Runnable() {
|
|
723
|
+
@Override
|
|
724
|
+
public void run() {
|
|
725
|
+
try {
|
|
726
|
+
if (webViewDialog != null) {
|
|
727
|
+
webViewDialog.executeScript(script);
|
|
728
|
+
call.resolve();
|
|
729
|
+
} else {
|
|
730
|
+
call.reject("WebView is not initialized");
|
|
731
|
+
}
|
|
732
|
+
} catch (Exception e) {
|
|
733
|
+
Log.e("InAppBrowser", "Error executing script: " + e.getMessage());
|
|
734
|
+
call.reject("Failed to execute script: " + e.getMessage());
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
);
|
|
826
739
|
}
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
740
|
+
|
|
741
|
+
@PluginMethod
|
|
742
|
+
public void goBack(PluginCall call) {
|
|
743
|
+
this.getActivity().runOnUiThread(
|
|
744
|
+
new Runnable() {
|
|
745
|
+
@Override
|
|
746
|
+
public void run() {
|
|
747
|
+
if (webViewDialog != null) {
|
|
748
|
+
boolean canGoBack = webViewDialog.goBack();
|
|
749
|
+
JSObject result = new JSObject();
|
|
750
|
+
result.put("canGoBack", canGoBack);
|
|
751
|
+
call.resolve(result);
|
|
752
|
+
} else {
|
|
753
|
+
JSObject result = new JSObject();
|
|
754
|
+
result.put("canGoBack", false);
|
|
755
|
+
call.resolve(result);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
);
|
|
835
760
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
761
|
+
|
|
762
|
+
@PluginMethod
|
|
763
|
+
public void reload(PluginCall call) {
|
|
764
|
+
this.getActivity().runOnUiThread(
|
|
765
|
+
new Runnable() {
|
|
766
|
+
@Override
|
|
767
|
+
public void run() {
|
|
768
|
+
if (webViewDialog != null) {
|
|
769
|
+
webViewDialog.reload();
|
|
770
|
+
call.resolve();
|
|
771
|
+
} else {
|
|
772
|
+
call.reject("WebView is not initialized");
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
);
|
|
841
777
|
}
|
|
842
778
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
779
|
+
@PluginMethod
|
|
780
|
+
public void lsuakdchgbbaHandleProxiedRequest(PluginCall call) {
|
|
781
|
+
if (webViewDialog != null) {
|
|
782
|
+
Boolean ok = call.getBoolean("ok", false);
|
|
783
|
+
String id = call.getString("id");
|
|
784
|
+
if (id == null) {
|
|
785
|
+
Log.e("InAppBrowserProxy", "CRITICAL ERROR, proxy id = null");
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
if (Boolean.FALSE.equals(ok)) {
|
|
789
|
+
String result = call.getString("result", "");
|
|
790
|
+
webViewDialog.handleProxyResultError(result, id);
|
|
852
791
|
} else {
|
|
853
|
-
|
|
792
|
+
JSONObject object = call.getObject("result");
|
|
793
|
+
webViewDialog.handleProxyResultOk(object, id);
|
|
854
794
|
}
|
|
855
|
-
}
|
|
856
795
|
}
|
|
857
|
-
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
@PluginMethod
|
|
861
|
-
public void executeScript(PluginCall call) {
|
|
862
|
-
String script = call.getString("code");
|
|
863
|
-
if (script == null || script.trim().isEmpty()) {
|
|
864
|
-
call.reject("Script is required");
|
|
865
|
-
return;
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
if (webViewDialog == null) {
|
|
869
|
-
call.reject("WebView is not initialized");
|
|
870
|
-
return;
|
|
796
|
+
call.resolve();
|
|
871
797
|
}
|
|
872
798
|
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
public void run() {
|
|
799
|
+
@PluginMethod
|
|
800
|
+
public void close(PluginCall call) {
|
|
801
|
+
if (webViewDialog == null) {
|
|
802
|
+
// Fallback: try to bring main activity to foreground
|
|
878
803
|
try {
|
|
879
|
-
|
|
880
|
-
|
|
804
|
+
Intent intent = new Intent(getContext(), getBridge().getActivity().getClass());
|
|
805
|
+
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
806
|
+
getContext().startActivity(intent);
|
|
881
807
|
call.resolve();
|
|
882
|
-
} else {
|
|
883
|
-
call.reject("WebView is not initialized");
|
|
884
|
-
}
|
|
885
808
|
} catch (Exception e) {
|
|
886
|
-
|
|
887
|
-
"
|
|
888
|
-
"Error executing script: " + e.getMessage()
|
|
889
|
-
);
|
|
890
|
-
call.reject("Failed to execute script: " + e.getMessage());
|
|
809
|
+
Log.e("InAppBrowser", "Error bringing main activity to foreground: " + e.getMessage());
|
|
810
|
+
call.reject("WebView is not initialized and failed to restore main activity");
|
|
891
811
|
}
|
|
892
|
-
|
|
812
|
+
return;
|
|
893
813
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
814
|
+
|
|
815
|
+
this.getActivity().runOnUiThread(
|
|
816
|
+
new Runnable() {
|
|
817
|
+
@Override
|
|
818
|
+
public void run() {
|
|
819
|
+
try {
|
|
820
|
+
if (webViewDialog != null) {
|
|
821
|
+
String currentUrl = "";
|
|
822
|
+
try {
|
|
823
|
+
currentUrl = webViewDialog.getUrl();
|
|
824
|
+
if (currentUrl == null) {
|
|
825
|
+
currentUrl = "";
|
|
826
|
+
}
|
|
827
|
+
} catch (Exception e) {
|
|
828
|
+
Log.e("InAppBrowser", "Error getting URL before close: " + e.getMessage());
|
|
829
|
+
currentUrl = "";
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// Notify listeners about the close event
|
|
833
|
+
notifyListeners("closeEvent", new JSObject().put("url", currentUrl));
|
|
834
|
+
|
|
835
|
+
webViewDialog.dismiss();
|
|
836
|
+
webViewDialog = null;
|
|
837
|
+
call.resolve();
|
|
838
|
+
} else {
|
|
839
|
+
// Secondary fallback inside UI thread
|
|
840
|
+
try {
|
|
841
|
+
Intent intent = new Intent(getContext(), getBridge().getActivity().getClass());
|
|
842
|
+
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
843
|
+
getContext().startActivity(intent);
|
|
844
|
+
call.resolve();
|
|
845
|
+
} catch (Exception e) {
|
|
846
|
+
Log.e("InAppBrowser", "Error in secondary fallback: " + e.getMessage());
|
|
847
|
+
call.reject("WebView is not initialized");
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
} catch (Exception e) {
|
|
851
|
+
Log.e("InAppBrowser", "Error closing WebView: " + e.getMessage());
|
|
852
|
+
call.reject("Failed to close WebView: " + e.getMessage());
|
|
853
|
+
}
|
|
854
|
+
}
|
|
931
855
|
}
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
);
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
@PluginMethod
|
|
938
|
-
public void lsuakdchgbbaHandleProxiedRequest(PluginCall call) {
|
|
939
|
-
if (webViewDialog != null) {
|
|
940
|
-
Boolean ok = call.getBoolean("ok", false);
|
|
941
|
-
String id = call.getString("id");
|
|
942
|
-
if (id == null) {
|
|
943
|
-
Log.e("InAppBrowserProxy", "CRITICAL ERROR, proxy id = null");
|
|
944
|
-
return;
|
|
945
|
-
}
|
|
946
|
-
if (Boolean.FALSE.equals(ok)) {
|
|
947
|
-
String result = call.getString("result", "");
|
|
948
|
-
webViewDialog.handleProxyResultError(result, id);
|
|
949
|
-
} else {
|
|
950
|
-
JSONObject object = call.getObject("result");
|
|
951
|
-
webViewDialog.handleProxyResultOk(object, id);
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
call.resolve();
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
@PluginMethod
|
|
958
|
-
public void close(PluginCall call) {
|
|
959
|
-
if (webViewDialog == null) {
|
|
960
|
-
// Fallback: try to bring main activity to foreground
|
|
961
|
-
try {
|
|
962
|
-
Intent intent = new Intent(
|
|
963
|
-
getContext(),
|
|
964
|
-
getBridge().getActivity().getClass()
|
|
965
856
|
);
|
|
966
|
-
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
967
|
-
getContext().startActivity(intent);
|
|
968
|
-
call.resolve();
|
|
969
|
-
} catch (Exception e) {
|
|
970
|
-
Log.e(
|
|
971
|
-
"InAppBrowser",
|
|
972
|
-
"Error bringing main activity to foreground: " + e.getMessage()
|
|
973
|
-
);
|
|
974
|
-
call.reject(
|
|
975
|
-
"WebView is not initialized and failed to restore main activity"
|
|
976
|
-
);
|
|
977
|
-
}
|
|
978
|
-
return;
|
|
979
857
|
}
|
|
980
858
|
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
new
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
try {
|
|
990
|
-
currentUrl = webViewDialog.getUrl();
|
|
991
|
-
if (currentUrl == null) {
|
|
992
|
-
currentUrl = "";
|
|
993
|
-
}
|
|
994
|
-
} catch (Exception e) {
|
|
995
|
-
Log.e(
|
|
996
|
-
"InAppBrowser",
|
|
997
|
-
"Error getting URL before close: " + e.getMessage()
|
|
998
|
-
);
|
|
999
|
-
currentUrl = "";
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
// Notify listeners about the close event
|
|
1003
|
-
notifyListeners(
|
|
1004
|
-
"closeEvent",
|
|
1005
|
-
new JSObject().put("url", currentUrl)
|
|
1006
|
-
);
|
|
1007
|
-
|
|
1008
|
-
webViewDialog.dismiss();
|
|
1009
|
-
webViewDialog = null;
|
|
1010
|
-
call.resolve();
|
|
1011
|
-
} else {
|
|
1012
|
-
// Secondary fallback inside UI thread
|
|
1013
|
-
try {
|
|
1014
|
-
Intent intent = new Intent(
|
|
1015
|
-
getContext(),
|
|
1016
|
-
getBridge().getActivity().getClass()
|
|
1017
|
-
);
|
|
1018
|
-
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
1019
|
-
getContext().startActivity(intent);
|
|
1020
|
-
call.resolve();
|
|
1021
|
-
} catch (Exception e) {
|
|
1022
|
-
Log.e(
|
|
1023
|
-
"InAppBrowser",
|
|
1024
|
-
"Error in secondary fallback: " + e.getMessage()
|
|
1025
|
-
);
|
|
1026
|
-
call.reject("WebView is not initialized");
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
} catch (Exception e) {
|
|
1030
|
-
Log.e("InAppBrowser", "Error closing WebView: " + e.getMessage());
|
|
1031
|
-
call.reject("Failed to close WebView: " + e.getMessage());
|
|
859
|
+
private Bundle getHeaders(PluginCall pluginCall) {
|
|
860
|
+
JSObject headersProvided = pluginCall.getObject("headers");
|
|
861
|
+
Bundle headers = new Bundle();
|
|
862
|
+
if (headersProvided != null) {
|
|
863
|
+
Iterator<String> keys = headersProvided.keys();
|
|
864
|
+
while (keys.hasNext()) {
|
|
865
|
+
String key = keys.next();
|
|
866
|
+
headers.putString(key, headersProvided.getString(key));
|
|
1032
867
|
}
|
|
1033
|
-
}
|
|
1034
868
|
}
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
while (keys.hasNext()) {
|
|
1044
|
-
String key = keys.next();
|
|
1045
|
-
headers.putString(key, headersProvided.getString(key));
|
|
1046
|
-
}
|
|
869
|
+
return headers;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
protected void handleOnResume() {
|
|
873
|
+
boolean ok = CustomTabsClient.bindCustomTabsService(getContext(), CUSTOM_TAB_PACKAGE_NAME, connection);
|
|
874
|
+
if (!ok) {
|
|
875
|
+
Log.e(getLogTag(), "Error binding to custom tabs service");
|
|
876
|
+
}
|
|
1047
877
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
protected void handleOnResume() {
|
|
1052
|
-
boolean ok = CustomTabsClient.bindCustomTabsService(
|
|
1053
|
-
getContext(),
|
|
1054
|
-
CUSTOM_TAB_PACKAGE_NAME,
|
|
1055
|
-
connection
|
|
1056
|
-
);
|
|
1057
|
-
if (!ok) {
|
|
1058
|
-
Log.e(getLogTag(), "Error binding to custom tabs service");
|
|
878
|
+
|
|
879
|
+
protected void handleOnPause() {
|
|
880
|
+
getContext().unbindService(connection);
|
|
1059
881
|
}
|
|
1060
|
-
}
|
|
1061
882
|
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
883
|
+
public CustomTabsSession getCustomTabsSession() {
|
|
884
|
+
if (customTabsClient == null) {
|
|
885
|
+
return null;
|
|
886
|
+
}
|
|
1065
887
|
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
888
|
+
if (currentSession == null) {
|
|
889
|
+
currentSession = customTabsClient.newSession(
|
|
890
|
+
new CustomTabsCallback() {
|
|
891
|
+
@Override
|
|
892
|
+
public void onNavigationEvent(int navigationEvent, Bundle extras) {
|
|
893
|
+
// Only fire browserPageLoaded for Custom Tabs, not for WebView
|
|
894
|
+
if (navigationEvent == NAVIGATION_FINISHED && webViewDialog == null) {
|
|
895
|
+
notifyListeners("browserPageLoaded", new JSObject());
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
return currentSession;
|
|
1069
902
|
}
|
|
1070
903
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
navigationEvent == NAVIGATION_FINISHED && webViewDialog == null
|
|
1079
|
-
) {
|
|
1080
|
-
notifyListeners("browserPageLoaded", new JSObject());
|
|
904
|
+
@Override
|
|
905
|
+
protected void handleOnDestroy() {
|
|
906
|
+
if (webViewDialog != null) {
|
|
907
|
+
try {
|
|
908
|
+
webViewDialog.dismiss();
|
|
909
|
+
} catch (Exception e) {
|
|
910
|
+
// Ignore, dialog may already be dismissed
|
|
1081
911
|
}
|
|
1082
|
-
|
|
912
|
+
webViewDialog = null;
|
|
1083
913
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
@Override
|
|
1090
|
-
protected void handleOnDestroy() {
|
|
1091
|
-
if (webViewDialog != null) {
|
|
1092
|
-
try {
|
|
1093
|
-
webViewDialog.dismiss();
|
|
1094
|
-
} catch (Exception e) {
|
|
1095
|
-
// Ignore, dialog may already be dismissed
|
|
1096
|
-
}
|
|
1097
|
-
webViewDialog = null;
|
|
914
|
+
currentPermissionRequest = null;
|
|
915
|
+
customTabsClient = null;
|
|
916
|
+
currentSession = null;
|
|
917
|
+
super.handleOnDestroy();
|
|
1098
918
|
}
|
|
1099
|
-
currentPermissionRequest = null;
|
|
1100
|
-
customTabsClient = null;
|
|
1101
|
-
currentSession = null;
|
|
1102
|
-
super.handleOnDestroy();
|
|
1103
|
-
}
|
|
1104
919
|
}
|