Skip to content

Commit b4e4b54

Browse files
committed
feat: implement StatusBar plugin JS API (SystemBarPlugin)
1 parent 54e222b commit b4e4b54

File tree

4 files changed

+145
-4
lines changed

4 files changed

+145
-4
lines changed

cordova-js-src/platform.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ module.exports = {
3939
// Core Splash Screen
4040
modulemapper.clobbers('cordova/plugin/android/splashscreen', 'navigator.splashscreen');
4141

42+
// Attach the internal statusBar utility to window.statusbar
43+
// see the file under plugin/android/statusbar.js
44+
modulemapper.clobbers('cordova/plugin/android/statusbar', 'window.statusbar');
45+
4246
var APP_PLUGIN_NAME = Number(cordova.platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
4347

4448
// Inject a listener for the backbutton on the document.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*
19+
*/
20+
21+
var exec = require('cordova/exec');
22+
23+
var statusBarVisible = true;
24+
var statusBar = {};
25+
26+
Object.defineProperty(statusBar, 'visible', {
27+
configurable: false,
28+
enumerable: true,
29+
get: function () {
30+
if (window.StatusBar) {
31+
// try to let the StatusBar plugin handle it
32+
return window.StatusBar.isVisible;
33+
}
34+
35+
return statusBarVisible;
36+
},
37+
set: function (value) {
38+
if (window.StatusBar) {
39+
// try to let the StatusBar plugin handle it
40+
if (value) {
41+
window.StatusBar.show();
42+
} else {
43+
window.StatusBar.hide();
44+
}
45+
} else {
46+
statusBarVisible = value;
47+
exec(null, null, 'SystemBarPlugin', 'setStatusBarVisible', [!!value]);
48+
}
49+
}
50+
});
51+
52+
Object.defineProperty(statusBar, 'setBackgroundColor', {
53+
configurable: false,
54+
enumerable: false,
55+
writable: false,
56+
value: function (value) {
57+
// Confirm if value is a valid hex code is before passing to native-side
58+
if (!(/^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value))) {
59+
console.error('Invalid color hex code. Valid format: #RRGGBB or #AARRGGBB');
60+
return;
61+
}
62+
63+
if (window.StatusBar) {
64+
window.StatusBar.backgroundColorByHexString(value);
65+
} else {
66+
exec(null, null, 'SystemBarPlugin', 'setStatusBarBackgroundColor', [value]);
67+
}
68+
}
69+
});
70+
71+
module.exports = statusBar;

framework/src/org/apache/cordova/CordovaActivity.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ Licensed to the Apache Software Foundation (ASF) under one
2929
import android.content.DialogInterface;
3030
import android.content.Intent;
3131
import android.content.res.Configuration;
32-
import android.graphics.Color;
3332
import android.media.AudioManager;
3433
import android.os.Build;
3534
import android.os.Bundle;
@@ -217,15 +216,18 @@ protected void createViews() {
217216
| WindowInsetsCompat.Type.displayCutout()
218217
);
219218

219+
boolean isStatusBarVisible = statusBarView.getVisibility() != View.GONE;
220+
int top = isStatusBarVisible ? bars.top : 0;
221+
220222
// Update the WebView's Margin LayoutParams
221223
FrameLayout.LayoutParams newParams = (FrameLayout.LayoutParams) webView.getLayoutParams();
222-
newParams.setMargins(bars.left, bars.top, bars.right, bars.bottom);
224+
newParams.setMargins(bars.left, top, bars.right, bars.bottom);
223225
webView.setLayoutParams(newParams);
224226

225227
// Position the status bar view to overlay the top inset areas
226228
statusBarView.setLayoutParams(new FrameLayout.LayoutParams(
227229
ViewGroup.LayoutParams.MATCH_PARENT,
228-
bars.top,
230+
top,
229231
Gravity.TOP
230232
));
231233

framework/src/org/apache/cordova/SystemBarPlugin.java

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,17 @@ Licensed to the Apache Software Foundation (ASF) under one
2929
import android.view.ViewParent;
3030
import android.view.Window;
3131
import android.view.WindowInsetsController;
32+
import android.view.WindowManager;
3233
import android.widget.FrameLayout;
3334

3435
import androidx.core.content.ContextCompat;
36+
import androidx.core.view.ViewCompat;
3537
import androidx.core.view.WindowCompat;
3638
import androidx.core.view.WindowInsetsControllerCompat;
3739

40+
import org.json.JSONArray;
41+
import org.json.JSONException;
42+
3843
public class SystemBarPlugin extends CordovaPlugin {
3944
static final String PLUGIN_NAME = "SystemBarPlugin";
4045

@@ -72,6 +77,63 @@ public Object onMessage(String id, Object data) {
7277
return null;
7378
}
7479

80+
@Override
81+
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
82+
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
83+
&& preferences.getBoolean("AndroidEdgeToEdge", false)
84+
) {
85+
// Disable JS API in E2E mode (SDK >= 35)
86+
return false;
87+
}
88+
89+
if ("setStatusBarVisible".equals(action)) {
90+
boolean visible = args.getBoolean(0);
91+
cordova.getActivity().runOnUiThread(() -> setStatusBarVisible(visible));
92+
} else if ("setStatusBarBackgroundColor".equals(action)) {
93+
String bgColor = args.getString(0);
94+
cordova.getActivity().runOnUiThread(() -> setStatusBarBackgroundColor(bgColor));
95+
} else {
96+
return false;
97+
}
98+
99+
callbackContext.success();
100+
return true;
101+
}
102+
103+
private void setStatusBarVisible(final boolean visible) {
104+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
105+
View statusBar = getStatusBarView(webView);
106+
if (statusBar != null) {
107+
statusBar.setVisibility(visible ? View.VISIBLE : View.GONE);
108+
109+
FrameLayout rootLayout = getRootLayout(webView);
110+
if (rootLayout != null) {
111+
ViewCompat.requestApplyInsets(rootLayout);
112+
}
113+
}
114+
} else {
115+
Window window = cordova.getActivity().getWindow();
116+
int uiOptions = window.getDecorView().getSystemUiVisibility();
117+
int flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN;
118+
if (visible) {
119+
uiOptions &= ~flags;
120+
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
121+
} else {
122+
uiOptions |= flags;
123+
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
124+
}
125+
window.getDecorView().setSystemUiVisibility(uiOptions);
126+
}
127+
}
128+
129+
private void setStatusBarBackgroundColor(final String colorPref) {
130+
int parsedColor = parseColorFromString(colorPref);
131+
if (parsedColor == INVALID_COLOR) return;
132+
133+
overrideStatusBarBackgroundColor = Color.parseColor(colorPref);
134+
updateStatusBar(overrideStatusBarBackgroundColor);
135+
}
136+
75137
private void updateSystemBars() {
76138
// Update Root View Background Color
77139
int rootViewBackgroundColor = getPreferenceBackgroundColor();
@@ -130,7 +192,9 @@ private void updateRootView(int bgColor) {
130192
private void updateStatusBar(int bgColor) {
131193
Window window = cordova.getActivity().getWindow();
132194

133-
if (!preferences.getBoolean("AndroidEdgeToEdge", false)) {
195+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
196+
&& !preferences.getBoolean("AndroidEdgeToEdge", false)
197+
) {
134198
View statusBar = getStatusBarView(webView);
135199
if (statusBar != null) {
136200
statusBar.setBackgroundColor(bgColor);

0 commit comments

Comments
 (0)