diff --git a/plugin.xml b/plugin.xml index c2b642c..233ebef 100644 --- a/plugin.xml +++ b/plugin.xml @@ -12,7 +12,7 @@ - + diff --git a/src/android/SafeInsets.java b/src/android/SafeInsets.java index e69de29..e7b33c1 100644 --- a/src/android/SafeInsets.java +++ b/src/android/SafeInsets.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.cordova.safeinsets; + +import android.app.Activity; +import android.os.Build; +import android.view.DisplayCutout; +import android.view.View; +import android.view.Window; +import android.view.WindowInsets; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaArgs; +import org.apache.cordova.CordovaInterface; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.LOG; +import org.apache.cordova.PluginResult; +import org.json.JSONException; +import org.json.JSONObject; + +public class SafeInsets extends CordovaPlugin { + + private static final String TAG = "SafeInsets"; + + private CallbackContext callbackContext; + + private final JSONObject insetsJSON = new JSONObject(); + + private float density; + + @Override + public void initialize(CordovaInterface cordova, CordovaWebView webView) { + super.initialize(cordova, webView); + + if (Build.VERSION.SDK_INT >= 20) { + final Activity activity = cordova.getActivity(); + final Window window = activity.getWindow(); + final View rootView = window.getDecorView().getRootView(); + + density = activity.getResources().getDisplayMetrics().density; + + rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { + @Override + public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { + if (Build.VERSION.SDK_INT < 28) { + updateInsets( + insets.getSystemWindowInsetTop(), + insets.getSystemWindowInsetRight(), + insets.getSystemWindowInsetBottom(), + insets.getStableInsetLeft() + ); + } else { + DisplayCutout cutout = insets.getDisplayCutout(); + updateInsets( + cutout.getSafeInsetTop(), + cutout.getSafeInsetRight(), + cutout.getSafeInsetBottom(), + cutout.getSafeInsetLeft() + ); + } + rootView.onApplyWindowInsets(insets); + return insets; + } + }); + } else { + LOG.v(TAG, "Required API level 20"); + } + } + + @Override + public boolean execute(final String action, final CordovaArgs args, final CallbackContext callbackContext) { + if ("check".equals(action)) { + PluginResult result = new PluginResult(PluginResult.Status.OK, insetsJSON); + result.setKeepCallback(true); + this.callbackContext = callbackContext; + callbackContext.sendPluginResult(result); + return true; + } + return false; + } + + private void updateInsets(int top, int right, int bottom, int left) { + try { + insetsJSON.put("top", top / density); + insetsJSON.put("bottom", bottom / density); + insetsJSON.put("left", left / density); + insetsJSON.put("right", right / density); + } catch (JSONException ex) {} + if (callbackContext != null) { + sendInsets(); + } + } + + private void sendInsets() { + PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, insetsJSON); + pluginResult.setKeepCallback(true); + callbackContext.sendPluginResult(pluginResult); + } +} \ No newline at end of file diff --git a/src/plugin.js b/src/plugin.js index cb78962..b03c31a 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -1,37 +1,26 @@ var exec = require('cordova/exec'); -// var _ready = false; -// -// var _callbacks = []; - var SafeInsets = { - - // ready: function(callback) { - // if (callback) { - // _ready ? callback() : _callbacks.push(callback); - // } - // return _ready; - // }, - top: 0, - right: 0, - bottom: 0, - left: 0 - }; -window.setTimeout(function () { - exec(function (insets) { - SafeInsets.top = insets.top; - SafeInsets.right = insets.right; - SafeInsets.bottom = insets.bottom; - SafeInsets.left = insets.left; - }, function (error) { - console.log('[SafeInsets] Error: ' + error); - }, "SafeInsets", "check"); -}, 0); +exec(function (insets) { + SafeInsets.top = insets.top; + SafeInsets.right = insets.right; + SafeInsets.bottom = insets.bottom; + SafeInsets.left = insets.left; + + var style = document.documentElement.style; + style.setProperty('--safe-inset-top', insets.top + 'px'); + style.setProperty('--safe-inset-right', insets.right + 'px'); + style.setProperty('--safe-inset-bottom', insets.bottom + 'px'); + style.setProperty('--safe-inset-left', insets.left + 'px'); + +}, function (error) { + console.log('[SafeInsets] Error: ' + error); +}, "SafeInsets", "check"); module.exports = SafeInsets; \ No newline at end of file