From 7c9c450984161dcb76858184fcb2d249b4dcf8f4 Mon Sep 17 00:00:00 2001 From: Kirill Zyusko Date: Tue, 3 Sep 2024 12:01:04 +0200 Subject: [PATCH] perf: use custom logger class (#577) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📜 Description Use own `Logger` class in Android. ## 💡 Motivation and Context Using own logger instance has many advantages: - we can implement internal implementation (like turn on/turn off logger depending on certain conditions); - we can change internals and forward logs to react-native js side if needed; - since it's our implementation we can change internals as we want and don't change the functionality in every piece of the code; - we can apply various optimization technique later on (such as inline functions etc.). So in this PR I'm introducing own `Logger` class and use it everywhere in the code. The main advantage of this class is that it's active only in debug mode and in release mode it will not send any logs (thus it'll slightly improve performance) and will not reveal details about the libraries that are used internally n the particular application. Later on I may add even more optimizations, such as inline functions etc. Closes https://github.com/kirillzyusko/react-native-keyboard-controller/issues/576 ## 📢 Changelog ### Android - added `Logger` class; - use `Logger` everywhere as alternative to `Log`. ## 🤔 How Has This Been Tested? ## 📸 Screenshots (if appropriate): |Before|After| |-------|-----| |image|image| ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed --- .../extensions/EditText.kt | 8 ++++---- .../extensions/ThemedReactContext.kt | 4 ++-- .../extensions/View.kt | 4 ++-- .../listeners/KeyboardAnimationCallback.kt | 10 +++++----- .../log/Logger.kt | 20 +++++++++++++++++++ .../modal/ModalAttachedWatcher.kt | 4 ++-- .../StatusBarManagerCompatModuleImpl.kt | 6 +++--- .../views/EdgeToEdgeReactViewGroup.kt | 4 ++-- 8 files changed, 40 insertions(+), 20 deletions(-) create mode 100644 android/src/main/java/com/reactnativekeyboardcontroller/log/Logger.kt diff --git a/android/src/main/java/com/reactnativekeyboardcontroller/extensions/EditText.kt b/android/src/main/java/com/reactnativekeyboardcontroller/extensions/EditText.kt index 371d3cecb5..3967c90d9c 100644 --- a/android/src/main/java/com/reactnativekeyboardcontroller/extensions/EditText.kt +++ b/android/src/main/java/com/reactnativekeyboardcontroller/extensions/EditText.kt @@ -3,11 +3,11 @@ package com.reactnativekeyboardcontroller.extensions import android.os.Build import android.text.Editable import android.text.TextWatcher -import android.util.Log import android.view.View import android.widget.EditText import com.facebook.react.views.scroll.ReactScrollView import com.facebook.react.views.textinput.ReactEditText +import com.reactnativekeyboardcontroller.log.Logger import com.reactnativekeyboardcontroller.ui.FrameScheduler import java.lang.reflect.Field import kotlin.math.max @@ -57,15 +57,15 @@ fun EditText.addOnTextChangedListener(action: (String) -> Unit): TextWatcher { textWatchListeners.add(0, listener) } else { - Log.w( + Logger.w( javaClass.simpleName, "Can not attach listener because `fieldValue` does not belong to `ArrayList`", ) } } catch (e: ClassCastException) { - Log.w(javaClass.simpleName, "Can not attach listener because casting failed: ${e.message}") + Logger.w(javaClass.simpleName, "Can not attach listener because casting failed: ${e.message}") } catch (e: NoSuchFieldException) { - Log.w(javaClass.simpleName, "Can not attach listener because field `mListeners` not found: ${e.message}") + Logger.w(javaClass.simpleName, "Can not attach listener because field `mListeners` not found: ${e.message}") } return listener diff --git a/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt b/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt index e0b681e5b2..d18de5f299 100644 --- a/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt +++ b/android/src/main/java/com/reactnativekeyboardcontroller/extensions/ThemedReactContext.kt @@ -1,6 +1,5 @@ package com.reactnativekeyboardcontroller.extensions -import android.util.Log import com.facebook.react.bridge.ReactContext import com.facebook.react.bridge.WritableMap import com.facebook.react.modules.core.DeviceEventManagerModule @@ -9,6 +8,7 @@ import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.uimanager.events.Event import com.facebook.react.uimanager.events.EventDispatcher import com.reactnativekeyboardcontroller.listeners.WindowDimensionListener +import com.reactnativekeyboardcontroller.log.Logger fun ThemedReactContext.setupWindowDimensionsListener() { WindowDimensionListener(this) @@ -25,5 +25,5 @@ fun ThemedReactContext?.emitEvent(event: String, params: WritableMap) { ?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) ?.emit(event, params) - Log.i("ThemedReactContext", event) + Logger.i("ThemedReactContext", event) } diff --git a/android/src/main/java/com/reactnativekeyboardcontroller/extensions/View.kt b/android/src/main/java/com/reactnativekeyboardcontroller/extensions/View.kt index 14af7c258e..d085d88c04 100644 --- a/android/src/main/java/com/reactnativekeyboardcontroller/extensions/View.kt +++ b/android/src/main/java/com/reactnativekeyboardcontroller/extensions/View.kt @@ -2,9 +2,9 @@ package com.reactnativekeyboardcontroller.extensions import android.graphics.Rect import android.os.Build -import android.util.Log import android.view.View import androidx.annotation.RequiresApi +import com.reactnativekeyboardcontroller.log.Logger /** * Call this every time when using [ViewCompat.setOnApplyWindowInsetsListener] @@ -43,7 +43,7 @@ fun View.copyBoundsInWindow(rect: Rect) { getLocationInWindow(tmpIntArr) rect.offset(tmpIntArr[0], tmpIntArr[1]) } else { - Log.w("View.copyBoundsInWindow", "Can not copy bounds as view is not attached to window") + Logger.w("View.copyBoundsInWindow", "Can not copy bounds as view is not attached to window") } } diff --git a/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt b/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt index a4bcfb5b0f..6c9169defb 100644 --- a/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt +++ b/android/src/main/java/com/reactnativekeyboardcontroller/listeners/KeyboardAnimationCallback.kt @@ -1,7 +1,6 @@ package com.reactnativekeyboardcontroller.listeners import android.os.Build -import android.util.Log import android.view.View import android.view.ViewTreeObserver.OnGlobalFocusChangeListener import androidx.core.graphics.Insets @@ -21,6 +20,7 @@ import com.reactnativekeyboardcontroller.extensions.dp import com.reactnativekeyboardcontroller.extensions.emitEvent import com.reactnativekeyboardcontroller.extensions.isKeyboardAnimation import com.reactnativekeyboardcontroller.interactive.InteractiveKeyboardProvider +import com.reactnativekeyboardcontroller.log.Logger import kotlin.math.abs private val TAG = KeyboardAnimationCallback::class.qualifiedName @@ -137,7 +137,7 @@ class KeyboardAnimationCallback( val isKeyboardSizeEqual = this.persistentKeyboardHeight == keyboardHeight if (isKeyboardFullyVisible && !isKeyboardSizeEqual && !isResizeHandledInCallbackMethods) { - Log.i(TAG, "onApplyWindowInsets: ${this.persistentKeyboardHeight} -> $keyboardHeight") + Logger.i(TAG, "onApplyWindowInsets: ${this.persistentKeyboardHeight} -> $keyboardHeight") layoutObserver?.syncUpLayout() this.onKeyboardResized(keyboardHeight) } @@ -182,7 +182,7 @@ class KeyboardAnimationCallback( getEventParams(keyboardHeight), ) - Log.i(TAG, "HEIGHT:: $keyboardHeight TAG:: $viewTagFocused") + Logger.i(TAG, "HEIGHT:: $keyboardHeight TAG:: $viewTagFocused") context.dispatchEvent( eventPropagationView.id, KeyboardTransitionEvent( @@ -229,9 +229,9 @@ class KeyboardAnimationCallback( progress = abs((height / persistentKeyboardHeight)).let { if (it.isNaN()) 0.0 else it } } catch (e: ArithmeticException) { // do nothing, just log an exception send progress as 0 - Log.w(TAG, "Caught arithmetic exception during `progress` calculation: $e") + Logger.w(TAG, "Caught arithmetic exception during `progress` calculation: $e") } - Log.i( + Logger.i( TAG, "DiffY: $diffY $height $progress ${InteractiveKeyboardProvider.isInteractive} $viewTagFocused", ) diff --git a/android/src/main/java/com/reactnativekeyboardcontroller/log/Logger.kt b/android/src/main/java/com/reactnativekeyboardcontroller/log/Logger.kt new file mode 100644 index 0000000000..25d343cd42 --- /dev/null +++ b/android/src/main/java/com/reactnativekeyboardcontroller/log/Logger.kt @@ -0,0 +1,20 @@ +package com.reactnativekeyboardcontroller.log + +import android.util.Log +import com.reactnativekeyboardcontroller.BuildConfig + +object Logger { + private val enabled = BuildConfig.DEBUG + + fun i(tag: String?, message: String, throwable: Throwable? = null) { + if (enabled) { + Log.i(tag, message, throwable) + } + } + + fun w(tag: String?, message: String, throwable: Throwable? = null) { + if (enabled) { + Log.w(tag, message, throwable) + } + } +} diff --git a/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt b/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt index cca784c6ef..595b6a1fe8 100644 --- a/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt +++ b/android/src/main/java/com/reactnativekeyboardcontroller/modal/ModalAttachedWatcher.kt @@ -1,6 +1,5 @@ package com.reactnativekeyboardcontroller.modal -import android.util.Log import android.view.WindowManager import androidx.core.view.ViewCompat import com.facebook.react.uimanager.ThemedReactContext @@ -13,6 +12,7 @@ import com.facebook.react.views.view.ReactViewGroup import com.reactnativekeyboardcontroller.BuildConfig import com.reactnativekeyboardcontroller.listeners.KeyboardAnimationCallback import com.reactnativekeyboardcontroller.listeners.KeyboardAnimationCallbackConfig +import com.reactnativekeyboardcontroller.log.Logger private val TAG = ModalAttachedWatcher::class.qualifiedName @@ -33,7 +33,7 @@ class ModalAttachedWatcher( val modal = try { uiManager?.resolveView(event.viewTag) as? ReactModalHostView } catch (ignore: Exception) { - Log.w(TAG, "Can not resolve view for Modal#${event.viewTag}", ignore) + Logger.w(TAG, "Can not resolve view for Modal#${event.viewTag}", ignore) null } diff --git a/android/src/main/java/com/reactnativekeyboardcontroller/modules/StatusBarManagerCompatModuleImpl.kt b/android/src/main/java/com/reactnativekeyboardcontroller/modules/StatusBarManagerCompatModuleImpl.kt index f1b2c2b2c0..cdfab3489e 100644 --- a/android/src/main/java/com/reactnativekeyboardcontroller/modules/StatusBarManagerCompatModuleImpl.kt +++ b/android/src/main/java/com/reactnativekeyboardcontroller/modules/StatusBarManagerCompatModuleImpl.kt @@ -3,13 +3,13 @@ package com.reactnativekeyboardcontroller.modules import android.animation.ArgbEvaluator import android.animation.ValueAnimator import android.os.Build -import android.util.Log import androidx.annotation.RequiresApi import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.UiThreadUtil import com.reactnativekeyboardcontroller.extensions.rootView +import com.reactnativekeyboardcontroller.log.Logger import com.reactnativekeyboardcontroller.views.EdgeToEdgeReactViewGroup private val TAG = StatusBarManagerCompatModuleImpl::class.qualifiedName @@ -31,7 +31,7 @@ class StatusBarManagerCompatModuleImpl(private val mReactContext: ReactApplicati fun setColor(color: Int, animated: Boolean) { val activity = mReactContext.currentActivity if (activity == null) { - Log.w(TAG, "StatusBarManagerCompatModule: Ignored status bar change, current activity is null.") + Logger.w(TAG, "StatusBarManagerCompatModule: Ignored status bar change, current activity is null.") return } @@ -69,7 +69,7 @@ class StatusBarManagerCompatModuleImpl(private val mReactContext: ReactApplicati if (this.controller == null) { val activity = mReactContext.currentActivity if (activity == null) { - Log.w( + Logger.w( TAG, "StatusBarManagerCompatModule: can not get `WindowInsetsControllerCompat` because current activity is null.", ) diff --git a/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt b/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt index 9418cf1c8a..2db1f5c8e0 100644 --- a/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt +++ b/android/src/main/java/com/reactnativekeyboardcontroller/views/EdgeToEdgeReactViewGroup.kt @@ -4,7 +4,6 @@ import android.annotation.SuppressLint import android.content.res.Configuration import android.os.Handler import android.os.Looper -import android.util.Log import android.widget.FrameLayout import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat @@ -19,6 +18,7 @@ import com.reactnativekeyboardcontroller.extensions.rootView import com.reactnativekeyboardcontroller.extensions.setupWindowDimensionsListener import com.reactnativekeyboardcontroller.listeners.KeyboardAnimationCallback import com.reactnativekeyboardcontroller.listeners.KeyboardAnimationCallbackConfig +import com.reactnativekeyboardcontroller.log.Logger import com.reactnativekeyboardcontroller.modal.ModalAttachedWatcher private val TAG = EdgeToEdgeReactViewGroup::class.qualifiedName @@ -149,7 +149,7 @@ class EdgeToEdgeReactViewGroup(private val reactContext: ThemedReactContext) : R it.requestApplyInsetsWhenAttached() } } else { - Log.w(TAG, "Can not setup keyboard animation listener, since `currentActivity` is null") + Logger.w(TAG, "Can not setup keyboard animation listener, since `currentActivity` is null") } }