@capacitor/android 9.0.0-alpha.6 → 9.0.0-alpha.7
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/capacitor/build.gradle +3 -3
- package/capacitor/proguard-rules.pro +0 -6
- package/capacitor/src/main/assets/native-bridge.js +0 -6
- package/capacitor/src/main/java/com/getcapacitor/Bridge.java +62 -123
- package/capacitor/src/main/java/com/getcapacitor/CapConfig.java +0 -119
- package/capacitor/src/main/java/com/getcapacitor/CordovaBridgeConfig.java +6 -0
- package/capacitor/src/main/java/com/getcapacitor/MessageHandler.java +0 -5
- package/capacitor/src/main/java/com/getcapacitor/Plugin.java +63 -249
- package/capacitor/src/main/java/com/getcapacitor/PluginCall.java +0 -43
- package/capacitor/src/main/java/com/getcapacitor/PluginHandle.java +7 -28
- package/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java +26 -0
- package/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java +86 -85
- package/capacitor-cordova/build.gradle +1 -1
- package/capacitor-cordova/src/main/java/com/getcapacitor/cordova/CordovaPlugin.java +8 -10
- package/package.json +2 -2
- package/capacitor/src/main/java/com/getcapacitor/NativePlugin.java +0 -37
|
@@ -4,11 +4,9 @@ import android.content.Context;
|
|
|
4
4
|
import android.content.pm.PackageInfo;
|
|
5
5
|
import android.content.res.Configuration;
|
|
6
6
|
import android.content.res.Resources;
|
|
7
|
-
import android.os.Build;
|
|
8
7
|
import android.util.TypedValue;
|
|
9
8
|
import android.view.View;
|
|
10
9
|
import android.view.Window;
|
|
11
|
-
import android.webkit.JavascriptInterface;
|
|
12
10
|
import android.webkit.WebView;
|
|
13
11
|
import androidx.core.graphics.Insets;
|
|
14
12
|
import androidx.core.view.ViewCompat;
|
|
@@ -33,9 +31,9 @@ public class SystemBars extends Plugin {
|
|
|
33
31
|
static final String BAR_STATUS_BAR = "StatusBar";
|
|
34
32
|
static final String BAR_GESTURE_BAR = "NavigationBar";
|
|
35
33
|
|
|
36
|
-
// TODO: In Cap 9, add an additional option "full"
|
|
37
34
|
static final String INSETS_HANDLING_CSS = "css";
|
|
38
35
|
static final String INSETS_HANDLING_DISABLE = "disable";
|
|
36
|
+
static final String INSETS_HANDLING_NATIVE = "native";
|
|
39
37
|
|
|
40
38
|
// https://issues.chromium.org/issues/40699457
|
|
41
39
|
private static final int WEBVIEW_VERSION_WITH_SAFE_AREA_FIX = 140;
|
|
@@ -43,27 +41,40 @@ public class SystemBars extends Plugin {
|
|
|
43
41
|
private static final int WEBVIEW_VERSION_WITH_SAFE_AREA_KEYBOARD_FIX = 144;
|
|
44
42
|
|
|
45
43
|
static final String viewportMetaJSFunction = """
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
// get the last found meta viewport tag
|
|
52
|
-
const metaContent = meta[meta.length - 1].content;
|
|
53
|
-
return metaContent.includes("viewport-fit=cover");
|
|
44
|
+
function capacitorSystemBarsCheckMetaViewport() {
|
|
45
|
+
const meta = document.querySelectorAll("meta[name=viewport]");
|
|
46
|
+
if (meta.length == 0) {
|
|
47
|
+
return false;
|
|
54
48
|
}
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
// get the last found meta viewport tag
|
|
50
|
+
const metaContent = meta[meta.length - 1].content;
|
|
51
|
+
return metaContent.includes("viewport-fit=cover");
|
|
52
|
+
}
|
|
53
|
+
capacitorSystemBarsCheckMetaViewport();
|
|
54
|
+
""";
|
|
57
55
|
|
|
58
|
-
private String insetsHandling =
|
|
56
|
+
private String insetsHandling = INSETS_HANDLING_NATIVE;
|
|
59
57
|
private boolean hasViewportCover = false;
|
|
60
58
|
|
|
61
59
|
private String currentStatusBarStyle = STYLE_DEFAULT;
|
|
62
60
|
private String currentGestureBarStyle = STYLE_DEFAULT;
|
|
63
61
|
|
|
62
|
+
// Declare variable at this scope to help prevent adding multiple listeners.
|
|
63
|
+
private WebViewListener webViewListener;
|
|
64
|
+
|
|
65
|
+
private void warnAboutUnsupportedConfigurationValues() {
|
|
66
|
+
boolean keyboardResizeOnFullScreen = bridge.getConfig().getPluginConfiguration("Keyboard").getBoolean("resizeOnFullScreen", false);
|
|
67
|
+
|
|
68
|
+
if (!INSETS_HANDLING_DISABLE.equals(insetsHandling) && keyboardResizeOnFullScreen) {
|
|
69
|
+
Logger.warn(
|
|
70
|
+
"SystemBars",
|
|
71
|
+
"You should omit `Keyboard.resizeOnFullScreen` in your `capacitor.config.json`. Other values can lead to unexpected behavior."
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
64
76
|
@Override
|
|
65
77
|
public void load() {
|
|
66
|
-
getBridge().getWebView().addJavascriptInterface(this, "CapacitorSystemBarsAndroidInterface");
|
|
67
78
|
super.load();
|
|
68
79
|
|
|
69
80
|
initSystemBars();
|
|
@@ -73,15 +84,25 @@ public class SystemBars extends Plugin {
|
|
|
73
84
|
protected void handleOnStart() {
|
|
74
85
|
super.handleOnStart();
|
|
75
86
|
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
if (INSETS_HANDLING_DISABLE.equals(insetsHandling)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (webViewListener == null) {
|
|
92
|
+
webViewListener = new WebViewListener() {
|
|
78
93
|
@Override
|
|
79
94
|
public void onPageCommitVisible(WebView view, String url) {
|
|
80
95
|
super.onPageCommitVisible(view, url);
|
|
81
|
-
|
|
96
|
+
bridge.getWebView().evaluateJavascript(viewportMetaJSFunction, (res) -> {
|
|
97
|
+
hasViewportCover = res.equals("true");
|
|
98
|
+
|
|
99
|
+
// Request new execution tree of `setOnApplyWindowInsetsListener`
|
|
100
|
+
bridge.getWebView().requestApplyInsets();
|
|
101
|
+
});
|
|
82
102
|
}
|
|
83
|
-
}
|
|
84
|
-
|
|
103
|
+
};
|
|
104
|
+
this.getBridge().addWebViewListener(webViewListener);
|
|
105
|
+
}
|
|
85
106
|
}
|
|
86
107
|
|
|
87
108
|
@Override
|
|
@@ -93,22 +114,32 @@ public class SystemBars extends Plugin {
|
|
|
93
114
|
}
|
|
94
115
|
|
|
95
116
|
private void initSystemBars() {
|
|
117
|
+
// If you already know what the value of the `viewport-fit=` meta tag is going to be,
|
|
118
|
+
// passing it here through `initialViewportFitValueHint` can help prevent layout shifting.
|
|
119
|
+
String configuredInitialViewportFitValueHint = getConfig().getString("initialViewportFitValueHint", "");
|
|
120
|
+
hasViewportCover = "cover".equals(configuredInitialViewportFitValueHint);
|
|
121
|
+
|
|
96
122
|
String style = getConfig().getString("style", STYLE_DEFAULT).toUpperCase(Locale.US);
|
|
97
123
|
boolean hidden = getConfig().getBoolean("hidden", false);
|
|
98
124
|
|
|
99
|
-
String configuredInsetsHandling = getConfig().getString("insetsHandling",
|
|
100
|
-
if (
|
|
125
|
+
String configuredInsetsHandling = getConfig().getString("insetsHandling", INSETS_HANDLING_NATIVE);
|
|
126
|
+
if (
|
|
127
|
+
INSETS_HANDLING_CSS.equals(configuredInsetsHandling) ||
|
|
128
|
+
INSETS_HANDLING_DISABLE.equals(configuredInsetsHandling) ||
|
|
129
|
+
INSETS_HANDLING_NATIVE.equals(configuredInsetsHandling)
|
|
130
|
+
) {
|
|
101
131
|
insetsHandling = configuredInsetsHandling;
|
|
102
132
|
} else {
|
|
103
133
|
Logger.warn(
|
|
104
134
|
"SystemBars",
|
|
105
|
-
"Unknown insetsHandling value '" + configuredInsetsHandling + "'. Falling back to '" +
|
|
135
|
+
"Unknown insetsHandling value '" + configuredInsetsHandling + "'. Falling back to '" + INSETS_HANDLING_NATIVE + "'."
|
|
106
136
|
);
|
|
107
|
-
insetsHandling =
|
|
137
|
+
insetsHandling = INSETS_HANDLING_NATIVE;
|
|
108
138
|
}
|
|
109
139
|
|
|
140
|
+
warnAboutUnsupportedConfigurationValues();
|
|
141
|
+
|
|
110
142
|
initWindowInsetsListener();
|
|
111
|
-
initSafeAreaCSSVariables();
|
|
112
143
|
|
|
113
144
|
getBridge().executeOnMainThread(() -> {
|
|
114
145
|
setStyle(style, "");
|
|
@@ -152,51 +183,14 @@ public class SystemBars extends Plugin {
|
|
|
152
183
|
call.resolve();
|
|
153
184
|
}
|
|
154
185
|
|
|
155
|
-
@JavascriptInterface
|
|
156
|
-
public void onDOMReady() {
|
|
157
|
-
if (INSETS_HANDLING_CSS.equals(insetsHandling)) {
|
|
158
|
-
getActivity().runOnUiThread(() -> {
|
|
159
|
-
this.bridge.getWebView().evaluateJavascript(viewportMetaJSFunction, (res) -> {
|
|
160
|
-
hasViewportCover = res.equals("true");
|
|
161
|
-
|
|
162
|
-
getBridge().getWebView().requestApplyInsets();
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
private Insets calcSafeAreaInsets(WindowInsetsCompat insets) {
|
|
169
|
-
Insets safeArea = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
|
|
170
|
-
if (insets.isVisible(WindowInsetsCompat.Type.ime())) {
|
|
171
|
-
return Insets.of(safeArea.left, safeArea.top, safeArea.right, 0);
|
|
172
|
-
}
|
|
173
|
-
return Insets.of(safeArea.left, safeArea.top, safeArea.right, safeArea.bottom);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
private void initSafeAreaCSSVariables() {
|
|
177
|
-
if (INSETS_HANDLING_CSS.equals(insetsHandling)) {
|
|
178
|
-
WindowInsetsCompat insets;
|
|
179
|
-
|
|
180
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
181
|
-
View v = (View) this.getBridge().getWebView().getParent();
|
|
182
|
-
insets = ViewCompat.getRootWindowInsets(v);
|
|
183
|
-
} else {
|
|
184
|
-
insets = WindowInsetsCompat.CONSUMED;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (insets != null) {
|
|
188
|
-
Insets safeAreaInsets = calcSafeAreaInsets(insets);
|
|
189
|
-
injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
186
|
private void initWindowInsetsListener() {
|
|
195
187
|
if (INSETS_HANDLING_DISABLE.equals(insetsHandling)) {
|
|
196
188
|
return;
|
|
197
189
|
}
|
|
198
190
|
|
|
199
|
-
|
|
191
|
+
View view = getActivity().getWindow().getDecorView();
|
|
192
|
+
|
|
193
|
+
ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> {
|
|
200
194
|
boolean shouldPassthroughInsets = getWebViewMajorVersion() >= WEBVIEW_VERSION_WITH_SAFE_AREA_FIX && hasViewportCover;
|
|
201
195
|
|
|
202
196
|
Insets systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
|
|
@@ -207,10 +201,7 @@ public class SystemBars extends Plugin {
|
|
|
207
201
|
// We need to correct for a possible shown IME
|
|
208
202
|
v.setPadding(0, 0, 0, keyboardVisible ? imeInsets.bottom : 0);
|
|
209
203
|
|
|
210
|
-
|
|
211
|
-
injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left);
|
|
212
|
-
|
|
213
|
-
return new WindowInsetsCompat.Builder(insets)
|
|
204
|
+
WindowInsetsCompat newInsets = new WindowInsetsCompat.Builder(insets)
|
|
214
205
|
.setInsets(
|
|
215
206
|
WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout(),
|
|
216
207
|
Insets.of(
|
|
@@ -221,18 +212,20 @@ public class SystemBars extends Plugin {
|
|
|
221
212
|
)
|
|
222
213
|
)
|
|
223
214
|
.build();
|
|
224
|
-
}
|
|
225
215
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
systemBarsInsets.left,
|
|
230
|
-
systemBarsInsets.top,
|
|
231
|
-
systemBarsInsets.right,
|
|
232
|
-
keyboardVisible ? imeInsets.bottom : systemBarsInsets.bottom
|
|
233
|
-
);
|
|
216
|
+
injectSafeAreaCSS(newInsets);
|
|
217
|
+
|
|
218
|
+
return newInsets;
|
|
234
219
|
}
|
|
235
220
|
|
|
221
|
+
// We need to correct for a possible shown IME
|
|
222
|
+
v.setPadding(
|
|
223
|
+
systemBarsInsets.left,
|
|
224
|
+
systemBarsInsets.top,
|
|
225
|
+
systemBarsInsets.right,
|
|
226
|
+
keyboardVisible ? imeInsets.bottom : systemBarsInsets.bottom
|
|
227
|
+
);
|
|
228
|
+
|
|
236
229
|
// Returning `WindowInsetsCompat.CONSUMED` breaks recalculation of safe area insets
|
|
237
230
|
// So we have to explicitly set insets to `0`
|
|
238
231
|
// See: https://issues.chromium.org/issues/461332423
|
|
@@ -240,20 +233,28 @@ public class SystemBars extends Plugin {
|
|
|
240
233
|
.setInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout(), Insets.of(0, 0, 0, 0))
|
|
241
234
|
.build();
|
|
242
235
|
|
|
243
|
-
|
|
244
|
-
injectSafeAreaCSS(safeAreaInsets.top, safeAreaInsets.right, safeAreaInsets.bottom, safeAreaInsets.left);
|
|
236
|
+
injectSafeAreaCSS(newInsets);
|
|
245
237
|
|
|
246
238
|
return newInsets;
|
|
247
239
|
});
|
|
248
240
|
}
|
|
249
241
|
|
|
250
|
-
private void injectSafeAreaCSS(
|
|
242
|
+
private void injectSafeAreaCSS(WindowInsetsCompat insets) {
|
|
243
|
+
if (!INSETS_HANDLING_CSS.equals(insetsHandling)) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
Insets systemBarsInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
|
|
248
|
+
boolean keyboardVisible = insets.isVisible(WindowInsetsCompat.Type.ime());
|
|
249
|
+
|
|
251
250
|
// Convert pixels to density-independent pixels
|
|
252
251
|
float density = getActivity().getResources().getDisplayMetrics().density;
|
|
253
|
-
float topPx = top / density;
|
|
254
|
-
float rightPx = right / density;
|
|
255
|
-
|
|
256
|
-
|
|
252
|
+
float topPx = systemBarsInsets.top / density;
|
|
253
|
+
float rightPx = systemBarsInsets.right / density;
|
|
254
|
+
// For native insets the value gets automatically corrected when the IME is visible (in newer WebView versions),
|
|
255
|
+
// but for these injected values we have to handle that manually (for all WebView versions).
|
|
256
|
+
float bottomPx = (keyboardVisible ? 0 : systemBarsInsets.bottom) / density;
|
|
257
|
+
float leftPx = systemBarsInsets.left / density;
|
|
257
258
|
|
|
258
259
|
// Execute JavaScript to inject the CSS
|
|
259
260
|
getBridge().executeOnMainThread(() -> {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
ext {
|
|
2
2
|
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
|
|
3
|
-
cordovaAndroidVersion = project.hasProperty('cordovaAndroidVersion') ? rootProject.ext.cordovaAndroidVersion : '
|
|
3
|
+
cordovaAndroidVersion = project.hasProperty('cordovaAndroidVersion') ? rootProject.ext.cordovaAndroidVersion : '15.0.0'
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
buildscript {
|
|
@@ -3,6 +3,7 @@ package com.getcapacitor.cordova;
|
|
|
3
3
|
import android.content.Intent;
|
|
4
4
|
import android.os.Bundle;
|
|
5
5
|
import android.webkit.WebView;
|
|
6
|
+
import com.getcapacitor.CordovaBridgeConfig;
|
|
6
7
|
import com.getcapacitor.Logger;
|
|
7
8
|
import com.getcapacitor.Plugin;
|
|
8
9
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
@@ -16,7 +17,7 @@ import org.apache.cordova.PluginManager;
|
|
|
16
17
|
import org.json.JSONException;
|
|
17
18
|
|
|
18
19
|
@CapacitorPlugin(name = "__CordovaPlugin")
|
|
19
|
-
public class CordovaPlugin extends Plugin {
|
|
20
|
+
public class CordovaPlugin extends Plugin implements CordovaBridgeConfig {
|
|
20
21
|
|
|
21
22
|
private MockCordovaInterfaceImpl cordovaInterface;
|
|
22
23
|
private CordovaWebView webView;
|
|
@@ -83,16 +84,13 @@ public class CordovaPlugin extends Plugin {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
@Override
|
|
86
|
-
public boolean
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (permission.equals("KeepRunning")) {
|
|
92
|
-
return preferences.getBoolean(permission, true);
|
|
93
|
-
}
|
|
87
|
+
public boolean shouldKeepRunning() {
|
|
88
|
+
return preferences.getBoolean("KeepRunning", true);
|
|
89
|
+
}
|
|
94
90
|
|
|
95
|
-
|
|
91
|
+
@Override
|
|
92
|
+
public boolean isDeployDisabled() {
|
|
93
|
+
return preferences.getBoolean("DisableDeploy", false);
|
|
96
94
|
}
|
|
97
95
|
|
|
98
96
|
@Override
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capacitor/android",
|
|
3
|
-
"version": "9.0.0-alpha.
|
|
3
|
+
"version": "9.0.0-alpha.7",
|
|
4
4
|
"description": "Capacitor: Cross-platform apps with JavaScript and the web",
|
|
5
5
|
"homepage": "https://capacitorjs.com",
|
|
6
6
|
"author": "Ionic Team <hi@ionic.io> (https://ionic.io)",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"verify": "./gradlew :capacitor-android:clean :capacitor-android:lint :capacitor-android:build :capacitor-android:test"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"@capacitor/core": "^9.0.0-alpha.
|
|
29
|
+
"@capacitor/core": "^9.0.0-alpha.7"
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"access": "public"
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
package com.getcapacitor;
|
|
2
|
-
|
|
3
|
-
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
4
|
-
import java.lang.annotation.Retention;
|
|
5
|
-
import java.lang.annotation.RetentionPolicy;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Base annotation for all Plugins
|
|
9
|
-
* @deprecated
|
|
10
|
-
* <p> Use {@link CapacitorPlugin} instead
|
|
11
|
-
*/
|
|
12
|
-
@Retention(RetentionPolicy.RUNTIME)
|
|
13
|
-
@Deprecated
|
|
14
|
-
public @interface NativePlugin {
|
|
15
|
-
/**
|
|
16
|
-
* Request codes this plugin uses and responds to, in order to tie
|
|
17
|
-
* Android events back the plugin to handle
|
|
18
|
-
*/
|
|
19
|
-
int[] requestCodes() default {};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Permissions this plugin needs, in order to make permission requests
|
|
23
|
-
* easy if the plugin only needs basic permission prompting
|
|
24
|
-
*/
|
|
25
|
-
String[] permissions() default {};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The request code to use when automatically requesting permissions
|
|
29
|
-
*/
|
|
30
|
-
int permissionRequestCode() default 9000;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* A custom name for the plugin, otherwise uses the
|
|
34
|
-
* simple class name.
|
|
35
|
-
*/
|
|
36
|
-
String name() default "";
|
|
37
|
-
}
|