From 793b7f056208cab1891d86579baae16dfa246aa7 Mon Sep 17 00:00:00 2001 From: otsmr Date: Fri, 1 May 2026 00:09:02 +0200 Subject: [PATCH] update deps --- config.lock.yaml | 4 +- .../numeric_fingerprint_generator.dart | 2 +- .../src/state/fingerprint_protocol.pb.dart | 6 - .../src/state/local_storage_protocol.pb.dart | 45 -- .../src/state/whisper_text_protocol.pb.dart | 18 - .../lib/src/util/byte_util.dart | 1 - libsignal_protocol_dart/pubspec.yaml | 6 +- .../no_screenshot/NoScreenshotPlugin.kt | 73 +-- .../no_screenshot/IOSNoScreenshotPlugin.swift | 2 +- no_screenshot/lib/no_screenshot.dart | 3 +- .../lib/no_screenshot_method_channel.dart | 31 +- .../lib/no_screenshot_platform_interface.dart | 23 +- no_screenshot/lib/no_screenshot_web.dart | 12 +- .../lib/secure_navigator_observer.dart | 7 +- no_screenshot/pubspec.yaml | 2 +- .../no_screenshot_method_channel_test.dart | 536 ++++++++---------- ...no_screenshot_platform_interface_test.dart | 257 ++++----- no_screenshot/test/no_screenshot_test.dart | 27 +- .../test/secure_navigator_observer_test.dart | 22 +- no_screenshot/test/secure_widget_test.dart | 58 +- 20 files changed, 440 insertions(+), 695 deletions(-) diff --git a/config.lock.yaml b/config.lock.yaml index a3d62e8..6cb8a41 100644 --- a/config.lock.yaml +++ b/config.lock.yaml @@ -7,10 +7,10 @@ hand_signature: 1beedb164d093643365b0832277c377353c7464f hashlib: bc9c2f8dd7bbc72f47ccab0ce1111d40259c49bc hashlib_codecs: 2a966c37c3b9b1f5541ae88e99ab34acf3fc968b introduction_screen: 4a90e557630b28834479ed9c64a9d2d0185d8e48 -libsignal_protocol_dart: 618f0c0b49534245a640a31d204265440cbac9ee +libsignal_protocol_dart: c95a1586057022acdbb9c76b1692d94cc549bcc7 lottie: 4f1a5a52bdf1e1c1e12fa97c96174dcb05419e19 mutex: 84ca903a3ac863735e3228c75a212133621f680f -no_screenshot: 1b561a2a87c19e317f3cb225ed023b113c9dd3a1 +no_screenshot: daf759e30219224630b4af0b82061d25a457a393 optional: 71c638891ce4f2aff35c7387727989f31f9d877d photo_view: a13ca2fc387a3fb1276126959e092c44d0029987 pointycastle: bbd8569f68a7fccbdf0b92d0b44a9219c126c8dd diff --git a/libsignal_protocol_dart/lib/src/fingerprint/numeric_fingerprint_generator.dart b/libsignal_protocol_dart/lib/src/fingerprint/numeric_fingerprint_generator.dart index 99becee..41a121c 100644 --- a/libsignal_protocol_dart/lib/src/fingerprint/numeric_fingerprint_generator.dart +++ b/libsignal_protocol_dart/lib/src/fingerprint/numeric_fingerprint_generator.dart @@ -70,7 +70,7 @@ class NumericFingerprintGenerator implements FingerprintGenerator { final sortedIdentityKeys = [...identityKeys]..sort(identityKeyComparator); final keys = []; - sortedIdentityKeys.forEach((IdentityKey key) { + sortedIdentityKeys.forEach((key) { final publicKeyBytes = key.publicKey.serialize(); keys.addAll(publicKeyBytes.toList()); }); diff --git a/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pb.dart b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pb.dart index 65f7476..cf629d8 100644 --- a/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pb.dart +++ b/libsignal_protocol_dart/lib/src/state/fingerprint_protocol.pb.dart @@ -62,9 +62,6 @@ class LogicalFingerprint extends $pb.GeneratedMessage { @override LogicalFingerprint createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static LogicalFingerprint getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -167,9 +164,6 @@ class CombinedFingerprints extends $pb.GeneratedMessage { @override CombinedFingerprints createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static CombinedFingerprints getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); diff --git a/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pb.dart b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pb.dart index 3328eee..cadd73f 100644 --- a/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pb.dart +++ b/libsignal_protocol_dart/lib/src/state/local_storage_protocol.pb.dart @@ -80,9 +80,6 @@ class SessionStructureChainChainKey extends $pb.GeneratedMessage { @override SessionStructureChainChainKey createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SessionStructureChainChainKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -214,9 +211,6 @@ class SessionStructureChainMessageKey extends $pb.GeneratedMessage { @override SessionStructureChainMessageKey createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SessionStructureChainMessageKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor( @@ -378,9 +372,6 @@ class SessionStructureChain extends $pb.GeneratedMessage { @override SessionStructureChain createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SessionStructureChain getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -565,9 +556,6 @@ class SessionStructurePendingKeyExchange extends $pb.GeneratedMessage { @override SessionStructurePendingKeyExchange createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SessionStructurePendingKeyExchange getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor( @@ -760,9 +748,6 @@ class SessionStructurePendingPreKey extends $pb.GeneratedMessage { @override SessionStructurePendingPreKey createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SessionStructurePendingPreKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -1004,9 +989,6 @@ class SessionStructure extends $pb.GeneratedMessage { @override SessionStructure createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SessionStructure getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -1266,9 +1248,6 @@ class RecordStructure extends $pb.GeneratedMessage { @override RecordStructure createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static RecordStructure getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -1379,9 +1358,6 @@ class PreKeyRecordStructure extends $pb.GeneratedMessage { @override PreKeyRecordStructure createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static PreKeyRecordStructure getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -1537,9 +1513,6 @@ class SignedPreKeyRecordStructure extends $pb.GeneratedMessage { @override SignedPreKeyRecordStructure createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SignedPreKeyRecordStructure getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -1690,9 +1663,6 @@ class IdentityKeyPairStructure extends $pb.GeneratedMessage { @override IdentityKeyPairStructure createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static IdentityKeyPairStructure getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -1802,9 +1772,6 @@ class SenderKeyStateStructureSenderChainKey extends $pb.GeneratedMessage { @override SenderKeyStateStructureSenderChainKey createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SenderKeyStateStructureSenderChainKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< @@ -1915,9 +1882,6 @@ class SenderKeyStateStructureSenderMessageKey extends $pb.GeneratedMessage { @override SenderKeyStateStructureSenderMessageKey createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SenderKeyStateStructureSenderMessageKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< @@ -2027,9 +1991,6 @@ class SenderKeyStateStructureSenderSigningKey extends $pb.GeneratedMessage { @override SenderKeyStateStructureSenderSigningKey createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SenderKeyStateStructureSenderSigningKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor< @@ -2162,9 +2123,6 @@ class SenderKeyStateStructure extends $pb.GeneratedMessage { @override SenderKeyStateStructure createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SenderKeyStateStructure getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -2288,9 +2246,6 @@ class SenderKeyRecordStructure extends $pb.GeneratedMessage { @override SenderKeyRecordStructure createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SenderKeyRecordStructure getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); diff --git a/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pb.dart b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pb.dart index 4dfedc0..6d1ac37 100644 --- a/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pb.dart +++ b/libsignal_protocol_dart/lib/src/state/whisper_text_protocol.pb.dart @@ -95,9 +95,6 @@ class SignalMessage extends $pb.GeneratedMessage { @override SignalMessage createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SignalMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -275,9 +272,6 @@ class PreKeySignalMessage extends $pb.GeneratedMessage { @override PreKeySignalMessage createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static PreKeySignalMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -473,9 +467,6 @@ class KeyExchangeMessage extends $pb.GeneratedMessage { @override KeyExchangeMessage createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static KeyExchangeMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -632,9 +623,6 @@ class SenderKeyMessage extends $pb.GeneratedMessage { @override SenderKeyMessage createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SenderKeyMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -779,9 +767,6 @@ class SenderKeyDistributionMessage extends $pb.GeneratedMessage { @override SenderKeyDistributionMessage createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static SenderKeyDistributionMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); @@ -918,9 +903,6 @@ class DeviceConsistencyCodeMessage extends $pb.GeneratedMessage { @override DeviceConsistencyCodeMessage createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') static DeviceConsistencyCodeMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); diff --git a/libsignal_protocol_dart/lib/src/util/byte_util.dart b/libsignal_protocol_dart/lib/src/util/byte_util.dart index 8de40ac..52b0325 100644 --- a/libsignal_protocol_dart/lib/src/util/byte_util.dart +++ b/libsignal_protocol_dart/lib/src/util/byte_util.dart @@ -72,7 +72,6 @@ class ByteUtil { } static int compare(Uint8List left, Uint8List right) { - // ignore: parameter_assignments, avoid_multiple_declarations_per_line for (var i = 0, j = 0; i < left.length && j < right.length; i++, j++) { final a = left[i] & 0xff; final b = right[j] & 0xff; diff --git a/libsignal_protocol_dart/pubspec.yaml b/libsignal_protocol_dart/pubspec.yaml index e039de7..573f8db 100644 --- a/libsignal_protocol_dart/pubspec.yaml +++ b/libsignal_protocol_dart/pubspec.yaml @@ -1,6 +1,6 @@ name: libsignal_protocol_dart description: Signal Protocol libray for Dart native and Flutter, pure Dart implementation of the the Signal Protocol -version: 0.7.4 +version: 0.8.0 repository: https://github.com/MixinNetwork/libsignal_protocol_dart topics: - crypto @@ -19,10 +19,10 @@ dependencies: meta: ^1.16.0 optional: ^6.1.0+1 pointycastle: ^4.0.0 - protobuf: ^4.0.0 + protobuf: ^6.0.0 x25519: ^0.1.1 dev_dependencies: test: ^1.25.8 - very_good_analysis: ^8.0.0 + very_good_analysis: ^10.2.0 diff --git a/no_screenshot/android/src/main/kotlin/com/flutterplaza/no_screenshot/NoScreenshotPlugin.kt b/no_screenshot/android/src/main/kotlin/com/flutterplaza/no_screenshot/NoScreenshotPlugin.kt index 1cfd0ba..0fee690 100644 --- a/no_screenshot/android/src/main/kotlin/com/flutterplaza/no_screenshot/NoScreenshotPlugin.kt +++ b/no_screenshot/android/src/main/kotlin/com/flutterplaza/no_screenshot/NoScreenshotPlugin.kt @@ -22,7 +22,6 @@ import android.renderscript.ScriptIntrinsicBlur import android.util.Log import android.view.View import android.view.ViewGroup -import android.view.WindowManager import android.view.WindowManager.LayoutParams import android.widget.FrameLayout import android.widget.ImageView @@ -88,7 +87,6 @@ class NoScreenshotPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, Activ private var isScreenRecording: Boolean = false private var isRecordingListening: Boolean = false private var screenCaptureCallback: Any? = null - private var screenRecordingCallback: Any? = null override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { context = flutterPluginBinding.applicationContext @@ -114,12 +112,12 @@ class NoScreenshotPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, Activ activity = binding.activity restoreScreenshotState() if (isRecordingListening) { - registerScreenRecordingCallbacks() + registerScreenCaptureCallback() } } override fun onDetachedFromActivityForConfigChanges() { - unregisterScreenRecordingCallbacks() + unregisterScreenCaptureCallback() removeImageOverlay() removeBlurOverlay() removeColorOverlay() @@ -130,12 +128,12 @@ class NoScreenshotPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, Activ activity = binding.activity restoreScreenshotState() if (isRecordingListening) { - registerScreenRecordingCallbacks() + registerScreenCaptureCallback() } } override fun onDetachedFromActivity() { - unregisterScreenRecordingCallbacks() + unregisterScreenCaptureCallback() removeImageOverlay() removeBlurOverlay() removeColorOverlay() @@ -273,7 +271,7 @@ class NoScreenshotPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, Activ private fun showImageOverlay(activity: Activity) { if (overlayImageView != null) return - val resId = activity.resources.getIdentifier("no_screenshot_image", "drawable", activity.packageName) + val resId = activity.resources.getIdentifier("image", "drawable", activity.packageName) if (resId == 0) return activity.runOnUiThread { val imageView = ImageView(activity).apply { @@ -546,77 +544,24 @@ class NoScreenshotPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, Activ } // ── Screen Recording Detection ───────────────────────────────────── - // - // API 35+ (Android 15): WindowManager.addScreenRecordingCallback - // → true start/stop detection via SCREEN_RECORDING_STATE_VISIBLE / _NOT_VISIBLE - // API 34 (Android 14): Activity.ScreenCaptureCallback - // → fires on screen capture (start only, no stop event) - // API <34: graceful no-op private fun startRecordingListening() { if (isRecordingListening) return isRecordingListening = true - registerScreenRecordingCallbacks() + registerScreenCaptureCallback() updateSharedPreferencesState("") } private fun stopRecordingListening() { if (!isRecordingListening) return isRecordingListening = false - unregisterScreenRecordingCallbacks() + unregisterScreenCaptureCallback() isScreenRecording = false updateSharedPreferencesState("") } - private fun registerScreenRecordingCallbacks() { - if (Build.VERSION.SDK_INT >= 35) { - registerScreenRecordingCallback() - } else if (Build.VERSION.SDK_INT >= 34) { - registerScreenCaptureCallback() - } - } - - private fun unregisterScreenRecordingCallbacks() { - if (Build.VERSION.SDK_INT >= 35) { - unregisterScreenRecordingCallback() - } - if (Build.VERSION.SDK_INT >= 34) { - unregisterScreenCaptureCallback() - } - } - - @Suppress("NewApi") - private fun registerScreenRecordingCallback() { - val act = activity ?: return - if (screenRecordingCallback != null) return - - val callback = java.util.function.Consumer { state -> - val wasRecording = isScreenRecording - isScreenRecording = (state == WindowManager.SCREEN_RECORDING_STATE_VISIBLE) - if (isScreenRecording != wasRecording) { - updateSharedPreferencesState("", System.currentTimeMillis()) - } - } - val initialState = act.windowManager.addScreenRecordingCallback(act.mainExecutor, callback) - screenRecordingCallback = callback - // Process initial state - val wasRecording = isScreenRecording - isScreenRecording = (initialState == WindowManager.SCREEN_RECORDING_STATE_VISIBLE) - if (isScreenRecording != wasRecording) { - updateSharedPreferencesState("", System.currentTimeMillis()) - } - } - - @Suppress("NewApi", "UNCHECKED_CAST") - private fun unregisterScreenRecordingCallback() { - val act = activity ?: return - val callback = screenRecordingCallback as? java.util.function.Consumer ?: return - act.windowManager.removeScreenRecordingCallback(callback) - screenRecordingCallback = null - } - private fun registerScreenCaptureCallback() { - if (Build.VERSION.SDK_INT >= 34) { + if (android.os.Build.VERSION.SDK_INT >= 34) { val act = activity ?: return if (screenCaptureCallback != null) return @@ -630,7 +575,7 @@ class NoScreenshotPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, Activ } private fun unregisterScreenCaptureCallback() { - if (Build.VERSION.SDK_INT >= 34) { + if (android.os.Build.VERSION.SDK_INT >= 34) { val act = activity ?: return val callback = screenCaptureCallback as? Activity.ScreenCaptureCallback ?: return act.unregisterScreenCaptureCallback(callback) diff --git a/no_screenshot/ios/no_screenshot/Sources/no_screenshot/IOSNoScreenshotPlugin.swift b/no_screenshot/ios/no_screenshot/Sources/no_screenshot/IOSNoScreenshotPlugin.swift index d23d6c7..5f0b300 100644 --- a/no_screenshot/ios/no_screenshot/Sources/no_screenshot/IOSNoScreenshotPlugin.swift +++ b/no_screenshot/ios/no_screenshot/Sources/no_screenshot/IOSNoScreenshotPlugin.swift @@ -138,7 +138,7 @@ public class IOSNoScreenshotPlugin: NSObject, FlutterPlugin, FlutterStreamHandle // visible in the app switcher (otherwise the secure text field // would show a blank screen). disablePreventScreenshot() - enableImageScreen(named: "NoScreenshotImage") + enableImageScreen(named: "image") } else if isBlurOverlayModeEnabled { disablePreventScreenshot() enableBlurScreen(radius: blurRadius) diff --git a/no_screenshot/lib/no_screenshot.dart b/no_screenshot/lib/no_screenshot.dart index b52ea17..2fad0c6 100644 --- a/no_screenshot/lib/no_screenshot.dart +++ b/no_screenshot/lib/no_screenshot.dart @@ -14,8 +14,7 @@ class NoScreenshot implements NoScreenshotPlatform { NoScreenshot._(); @Deprecated( - "Using this may cause issue\nUse instance directly\ne.g: 'NoScreenshot.instance.screenshotOff()'", - ) + "Using this may cause issue\nUse instance directly\ne.g: 'NoScreenshot.instance.screenshotOff()'") NoScreenshot(); static final NoScreenshot instance = NoScreenshot._(); diff --git a/no_screenshot/lib/no_screenshot_method_channel.dart b/no_screenshot/lib/no_screenshot_method_channel.dart index cd7f59a..f591480 100644 --- a/no_screenshot/lib/no_screenshot_method_channel.dart +++ b/no_screenshot/lib/no_screenshot_method_channel.dart @@ -19,18 +19,15 @@ class MethodChannelNoScreenshot extends NoScreenshotPlatform { @override Stream get screenshotStream { - _cachedStream ??= eventChannel.receiveBroadcastStream().map( - (event) => - ScreenshotSnapshot.fromMap(jsonDecode(event) as Map), - ); + _cachedStream ??= eventChannel.receiveBroadcastStream().map((event) => + ScreenshotSnapshot.fromMap(jsonDecode(event) as Map)); return _cachedStream!; } @override Future toggleScreenshot() async { - final result = await methodChannel.invokeMethod( - toggleScreenShotConst, - ); + final result = + await methodChannel.invokeMethod(toggleScreenShotConst); return result ?? false; } @@ -54,17 +51,15 @@ class MethodChannelNoScreenshot extends NoScreenshotPlatform { @override Future toggleScreenshotWithBlur({double blurRadius = 30.0}) async { - final result = await methodChannel.invokeMethod(screenSetBlur, { - 'radius': blurRadius, - }); + final result = await methodChannel + .invokeMethod(screenSetBlur, {'radius': blurRadius}); return result ?? false; } @override Future toggleScreenshotWithColor({int color = 0xFF000000}) async { - final result = await methodChannel.invokeMethod(screenSetColor, { - 'color': color, - }); + final result = await methodChannel + .invokeMethod(screenSetColor, {'color': color}); return result ?? false; } @@ -76,17 +71,15 @@ class MethodChannelNoScreenshot extends NoScreenshotPlatform { @override Future screenshotWithBlur({double blurRadius = 30.0}) async { - final result = await methodChannel.invokeMethod(screenEnableBlur, { - 'radius': blurRadius, - }); + final result = await methodChannel + .invokeMethod(screenEnableBlur, {'radius': blurRadius}); return result ?? false; } @override Future screenshotWithColor({int color = 0xFF000000}) async { - final result = await methodChannel.invokeMethod(screenEnableColor, { - 'color': color, - }); + final result = await methodChannel + .invokeMethod(screenEnableColor, {'color': color}); return result ?? false; } diff --git a/no_screenshot/lib/no_screenshot_platform_interface.dart b/no_screenshot/lib/no_screenshot_platform_interface.dart index 05d9876..f9ac29e 100644 --- a/no_screenshot/lib/no_screenshot_platform_interface.dart +++ b/no_screenshot/lib/no_screenshot_platform_interface.dart @@ -43,20 +43,17 @@ abstract class NoScreenshotPlatform extends PlatformInterface { /// throw `UnmimplementedError` if not implement Future toggleScreenshotWithImage() { throw UnimplementedError( - 'toggleScreenshotWithImage() has not been implemented.', - ); + 'toggleScreenshotWithImage() has not been implemented.'); } Future toggleScreenshotWithBlur({double blurRadius = 30.0}) { throw UnimplementedError( - 'toggleScreenshotWithBlur() has not been implemented.', - ); + 'toggleScreenshotWithBlur() has not been implemented.'); } Future toggleScreenshotWithColor({int color = 0xFF000000}) { throw UnimplementedError( - 'toggleScreenshotWithColor() has not been implemented.', - ); + 'toggleScreenshotWithColor() has not been implemented.'); } /// Always enables image overlay mode (idempotent — safe to call repeatedly). @@ -90,31 +87,27 @@ abstract class NoScreenshotPlatform extends PlatformInterface { throw UnimplementedError('incrementStream has not been implemented.'); } - // Start listening to screenshot activities +// Start listening to screenshot activities Future startScreenshotListening() { throw UnimplementedError( - 'startScreenshotListening has not been implemented.', - ); + 'startScreenshotListening has not been implemented.'); } /// Stop listening to screenshot activities Future stopScreenshotListening() { throw UnimplementedError( - 'stopScreenshotListening has not been implemented.', - ); + 'stopScreenshotListening has not been implemented.'); } /// Start listening to screen recording activities Future startScreenRecordingListening() { throw UnimplementedError( - 'startScreenRecordingListening has not been implemented.', - ); + 'startScreenRecordingListening has not been implemented.'); } /// Stop listening to screen recording activities Future stopScreenRecordingListening() { throw UnimplementedError( - 'stopScreenRecordingListening has not been implemented.', - ); + 'stopScreenRecordingListening has not been implemented.'); } } diff --git a/no_screenshot/lib/no_screenshot_web.dart b/no_screenshot/lib/no_screenshot_web.dart index dd970fc..fe7e0e8 100644 --- a/no_screenshot/lib/no_screenshot_web.dart +++ b/no_screenshot/lib/no_screenshot_web.dart @@ -138,13 +138,11 @@ class NoScreenshotWeb extends NoScreenshotPlatform { } void _emitState({bool wasScreenshotTaken = false}) { - _controller.add( - ScreenshotSnapshot( - screenshotPath: '', - isScreenshotProtectionOn: _isProtectionOn, - wasScreenshotTaken: wasScreenshotTaken, - ), - ); + _controller.add(ScreenshotSnapshot( + screenshotPath: '', + isScreenshotProtectionOn: _isProtectionOn, + wasScreenshotTaken: wasScreenshotTaken, + )); } // ── Context menu blocker ─────────────────────────────────────────── diff --git a/no_screenshot/lib/secure_navigator_observer.dart b/no_screenshot/lib/secure_navigator_observer.dart index abfa2b5..b6325e6 100644 --- a/no_screenshot/lib/secure_navigator_observer.dart +++ b/no_screenshot/lib/secure_navigator_observer.dart @@ -73,10 +73,7 @@ class SecureNavigatorObserver extends NavigatorObserver { void _applyPolicyForRoute(Route? route) { final name = route?.settings.name; final config = (name != null ? policies[name] : null) ?? defaultConfig; - applyOverlayMode( - config.mode, - blurRadius: config.blurRadius, - color: config.color, - ); + applyOverlayMode(config.mode, + blurRadius: config.blurRadius, color: config.color); } } diff --git a/no_screenshot/pubspec.yaml b/no_screenshot/pubspec.yaml index 9bf25a1..00e2ad7 100644 --- a/no_screenshot/pubspec.yaml +++ b/no_screenshot/pubspec.yaml @@ -1,6 +1,6 @@ name: no_screenshot description: Flutter plugin to prevent screenshots, detect screen recording, and show blur/color/image overlays in the app switcher on Android, iOS, macOS, Linux, Windows, and Web. -version: 1.1.0 +version: 0.10.0 homepage: https://flutterplaza.com repository: https://github.com/FlutterPlaza/no_screenshot diff --git a/no_screenshot/test/no_screenshot_method_channel_test.dart b/no_screenshot/test/no_screenshot_method_channel_test.dart index d383c30..1f5cfe7 100644 --- a/no_screenshot/test/no_screenshot_method_channel_test.dart +++ b/no_screenshot/test/no_screenshot_method_channel_test.dart @@ -25,11 +25,11 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenShotOnConst) { - return expected; - } - return null; - }); + if (methodCall.method == screenShotOnConst) { + return expected; + } + return null; + }); final result = await platform.screenshotOn(); expect(result, expected); @@ -39,11 +39,11 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenShotOffConst) { - return expected; - } - return null; - }); + if (methodCall.method == screenShotOffConst) { + return expected; + } + return null; + }); final result = await platform.screenshotOff(); expect(result, expected); @@ -53,11 +53,11 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == toggleScreenShotConst) { - return expected; - } - return null; - }); + if (methodCall.method == toggleScreenShotConst) { + return expected; + } + return null; + }); final result = await platform.toggleScreenshot(); expect(result, expected); @@ -66,11 +66,11 @@ void main() { test('startScreenshotListening', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == startScreenshotListeningConst) { - return null; - } - return null; - }); + if (methodCall.method == startScreenshotListeningConst) { + return null; + } + return null; + }); await platform.startScreenshotListening(); expect(true, true); // Add more specific expectations if needed @@ -79,11 +79,11 @@ void main() { test('stopScreenshotListening', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == stopScreenshotListeningConst) { - return null; - } - return null; - }); + if (methodCall.method == stopScreenshotListeningConst) { + return null; + } + return null; + }); await platform.stopScreenshotListening(); expect(true, true); // Add more specific expectations if needed @@ -93,11 +93,11 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenSetImage) { - return expected; - } - return null; - }); + if (methodCall.method == screenSetImage) { + return expected; + } + return null; + }); final result = await platform.toggleScreenshotWithImage(); expect(result, expected); @@ -107,12 +107,12 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenSetBlur) { - expect(methodCall.arguments, {'radius': 30.0}); - return expected; - } - return null; - }); + if (methodCall.method == screenSetBlur) { + expect(methodCall.arguments, {'radius': 30.0}); + return expected; + } + return null; + }); final result = await platform.toggleScreenshotWithBlur(); expect(result, expected); @@ -122,40 +122,38 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenSetBlur) { - expect(methodCall.arguments, {'radius': 50.0}); - return expected; - } - return null; - }); + if (methodCall.method == screenSetBlur) { + expect(methodCall.arguments, {'radius': 50.0}); + return expected; + } + return null; + }); final result = await platform.toggleScreenshotWithBlur(blurRadius: 50.0); expect(result, expected); }); - test( - 'toggleScreenshotWithBlur returns false when channel returns null', - () async { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - return null; - }); + test('toggleScreenshotWithBlur returns false when channel returns null', + () async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + return null; + }); - final result = await platform.toggleScreenshotWithBlur(); - expect(result, false); - }, - ); + final result = await platform.toggleScreenshotWithBlur(); + expect(result, false); + }); test('toggleScreenshotWithColor', () async { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenSetColor) { - expect(methodCall.arguments, {'color': 0xFF000000}); - return expected; - } - return null; - }); + if (methodCall.method == screenSetColor) { + expect(methodCall.arguments, {'color': 0xFF000000}); + return expected; + } + return null; + }); final result = await platform.toggleScreenshotWithColor(); expect(result, expected); @@ -165,50 +163,45 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenSetColor) { - expect(methodCall.arguments, {'color': 0xFFFF0000}); - return expected; - } - return null; - }); + if (methodCall.method == screenSetColor) { + expect(methodCall.arguments, {'color': 0xFFFF0000}); + return expected; + } + return null; + }); - final result = await platform.toggleScreenshotWithColor( - color: 0xFFFF0000, - ); + final result = + await platform.toggleScreenshotWithColor(color: 0xFFFF0000); expect(result, expected); }); - test( - 'toggleScreenshotWithColor returns false when channel returns null', - () async { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - return null; - }); + test('toggleScreenshotWithColor returns false when channel returns null', + () async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + return null; + }); - final result = await platform.toggleScreenshotWithColor(); - expect(result, false); - }, - ); + final result = await platform.toggleScreenshotWithColor(); + expect(result, false); + }); - test( - 'toggleScreenshotWithImage returns false when channel returns null', - () async { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - return null; - }); + test('toggleScreenshotWithImage returns false when channel returns null', + () async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + return null; + }); - final result = await platform.toggleScreenshotWithImage(); - expect(result, false); - }, - ); + final result = await platform.toggleScreenshotWithImage(); + expect(result, false); + }); test('screenshotOn returns false when channel returns null', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - return null; - }); + return null; + }); final result = await platform.screenshotOn(); expect(result, false); @@ -217,8 +210,8 @@ void main() { test('screenshotOff returns false when channel returns null', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - return null; - }); + return null; + }); final result = await platform.screenshotOff(); expect(result, false); @@ -227,8 +220,8 @@ void main() { test('toggleScreenshot returns false when channel returns null', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - return null; - }); + return null; + }); final result = await platform.toggleScreenshot(); expect(result, false); @@ -238,39 +231,37 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenEnableImage) { - return expected; - } - return null; - }); + if (methodCall.method == screenEnableImage) { + return expected; + } + return null; + }); final result = await platform.screenshotWithImage(); expect(result, expected); }); - test( - 'screenshotWithImage returns false when channel returns null', - () async { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - return null; - }); + test('screenshotWithImage returns false when channel returns null', + () async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + return null; + }); - final result = await platform.screenshotWithImage(); - expect(result, false); - }, - ); + final result = await platform.screenshotWithImage(); + expect(result, false); + }); test('screenshotWithBlur', () async { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenEnableBlur) { - expect(methodCall.arguments, {'radius': 30.0}); - return expected; - } - return null; - }); + if (methodCall.method == screenEnableBlur) { + expect(methodCall.arguments, {'radius': 30.0}); + return expected; + } + return null; + }); final result = await platform.screenshotWithBlur(); expect(result, expected); @@ -280,40 +271,38 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenEnableBlur) { - expect(methodCall.arguments, {'radius': 50.0}); - return expected; - } - return null; - }); + if (methodCall.method == screenEnableBlur) { + expect(methodCall.arguments, {'radius': 50.0}); + return expected; + } + return null; + }); final result = await platform.screenshotWithBlur(blurRadius: 50.0); expect(result, expected); }); - test( - 'screenshotWithBlur returns false when channel returns null', - () async { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - return null; - }); + test('screenshotWithBlur returns false when channel returns null', + () async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + return null; + }); - final result = await platform.screenshotWithBlur(); - expect(result, false); - }, - ); + final result = await platform.screenshotWithBlur(); + expect(result, false); + }); test('screenshotWithColor', () async { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenEnableColor) { - expect(methodCall.arguments, {'color': 0xFF000000}); - return expected; - } - return null; - }); + if (methodCall.method == screenEnableColor) { + expect(methodCall.arguments, {'color': 0xFF000000}); + return expected; + } + return null; + }); final result = await platform.screenshotWithColor(); expect(result, expected); @@ -323,38 +312,36 @@ void main() { const bool expected = true; TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == screenEnableColor) { - expect(methodCall.arguments, {'color': 0xFFFF0000}); - return expected; - } - return null; - }); + if (methodCall.method == screenEnableColor) { + expect(methodCall.arguments, {'color': 0xFFFF0000}); + return expected; + } + return null; + }); final result = await platform.screenshotWithColor(color: 0xFFFF0000); expect(result, expected); }); - test( - 'screenshotWithColor returns false when channel returns null', - () async { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - return null; - }); + test('screenshotWithColor returns false when channel returns null', + () async { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + return null; + }); - final result = await platform.screenshotWithColor(); - expect(result, false); - }, - ); + final result = await platform.screenshotWithColor(); + expect(result, false); + }); test('startScreenRecordingListening', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == startScreenRecordingListeningConst) { - return null; - } - return null; - }); + if (methodCall.method == startScreenRecordingListeningConst) { + return null; + } + return null; + }); await platform.startScreenRecordingListening(); expect(true, true); @@ -363,48 +350,43 @@ void main() { test('stopScreenRecordingListening', () async { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - if (methodCall.method == stopScreenRecordingListeningConst) { - return null; - } - return null; - }); + if (methodCall.method == stopScreenRecordingListeningConst) { + return null; + } + return null; + }); await platform.stopScreenRecordingListening(); expect(true, true); }); - test( - 'screenshotStream returns a stream that emits ScreenshotSnapshot', - () async { - final snapshotMap = { - 'screenshot_path': '/test/path', - 'is_screenshot_on': true, - 'was_screenshot_taken': true, - 'is_screen_recording': false, - 'timestamp': 0, - 'source_app': '', - }; - final encoded = jsonEncode(snapshotMap); + test('screenshotStream returns a stream that emits ScreenshotSnapshot', + () async { + final snapshotMap = { + 'screenshot_path': '/test/path', + 'is_screenshot_on': true, + 'was_screenshot_taken': true, + 'is_screen_recording': false, + 'timestamp': 0, + 'source_app': '', + }; + final encoded = jsonEncode(snapshotMap); - // Mock the event channel by handling the underlying method channel - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockStreamHandler( - platform.eventChannel, - MockStreamHandler.inline( - onListen: (arguments, events) { - events.success(encoded); - }, - ), - ); + // Mock the event channel by handling the underlying method channel + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger + .setMockStreamHandler(platform.eventChannel, MockStreamHandler.inline( + onListen: (arguments, events) { + events.success(encoded); + }, + )); - final stream = platform.screenshotStream; - final snapshot = await stream.first; + final stream = platform.screenshotStream; + final snapshot = await stream.first; - expect(snapshot.screenshotPath, '/test/path'); - expect(snapshot.isScreenshotProtectionOn, true); - expect(snapshot.wasScreenshotTaken, true); - }, - ); + expect(snapshot.screenshotPath, '/test/path'); + expect(snapshot.isScreenshotProtectionOn, true); + expect(snapshot.wasScreenshotTaken, true); + }); test('screenshotStream caches and returns the same stream instance', () { final stream1 = platform.screenshotStream; @@ -635,10 +617,8 @@ void main() { wasScreenshotTaken: true, ); final string = snapshot.toString(); - expect( - string, - 'ScreenshotSnapshot(\nscreenshotPath: /example/path, \nisScreenshotProtectionOn: true, \nwasScreenshotTaken: true, \nisScreenRecording: false, \ntimestamp: 0, \nsourceApp: \n)', - ); + expect(string, + 'ScreenshotSnapshot(\nscreenshotPath: /example/path, \nisScreenshotProtectionOn: true, \nwasScreenshotTaken: true, \nisScreenRecording: false, \ntimestamp: 0, \nsourceApp: \n)'); }); test('toString with isScreenRecording true', () { @@ -649,10 +629,8 @@ void main() { isScreenRecording: true, ); final string = snapshot.toString(); - expect( - string, - 'ScreenshotSnapshot(\nscreenshotPath: /example/path, \nisScreenshotProtectionOn: true, \nwasScreenshotTaken: true, \nisScreenRecording: true, \ntimestamp: 0, \nsourceApp: \n)', - ); + expect(string, + 'ScreenshotSnapshot(\nscreenshotPath: /example/path, \nisScreenshotProtectionOn: true, \nwasScreenshotTaken: true, \nisScreenRecording: true, \ntimestamp: 0, \nsourceApp: \n)'); }); test('toString with metadata', () { @@ -688,46 +666,38 @@ void main() { controller.close(); }); - test( - 'onScreenshotDetected fires when wasScreenshotTaken is true', - () async { - final detected = []; - noScreenshot.onScreenshotDetected = detected.add; - noScreenshot.startCallbacks(); + test('onScreenshotDetected fires when wasScreenshotTaken is true', + () async { + final detected = []; + noScreenshot.onScreenshotDetected = detected.add; + noScreenshot.startCallbacks(); - controller.add( - ScreenshotSnapshot( - screenshotPath: '/path', - isScreenshotProtectionOn: true, - wasScreenshotTaken: true, - ), - ); - await Future.delayed(Duration.zero); + controller.add(ScreenshotSnapshot( + screenshotPath: '/path', + isScreenshotProtectionOn: true, + wasScreenshotTaken: true, + )); + await Future.delayed(Duration.zero); - expect(detected, hasLength(1)); - expect(detected.first.wasScreenshotTaken, true); - }, - ); + expect(detected, hasLength(1)); + expect(detected.first.wasScreenshotTaken, true); + }); - test( - 'onScreenshotDetected does NOT fire when wasScreenshotTaken is false', - () async { - final detected = []; - noScreenshot.onScreenshotDetected = detected.add; - noScreenshot.startCallbacks(); + test('onScreenshotDetected does NOT fire when wasScreenshotTaken is false', + () async { + final detected = []; + noScreenshot.onScreenshotDetected = detected.add; + noScreenshot.startCallbacks(); - controller.add( - ScreenshotSnapshot( - screenshotPath: '', - isScreenshotProtectionOn: true, - wasScreenshotTaken: false, - ), - ); - await Future.delayed(Duration.zero); + controller.add(ScreenshotSnapshot( + screenshotPath: '', + isScreenshotProtectionOn: true, + wasScreenshotTaken: false, + )); + await Future.delayed(Duration.zero); - expect(detected, isEmpty); - }, - ); + expect(detected, isEmpty); + }); test('onScreenRecordingStarted fires on false→true transition', () async { final started = []; @@ -735,14 +705,12 @@ void main() { noScreenshot.startCallbacks(); // Initial state: not recording → recording starts - controller.add( - ScreenshotSnapshot( - screenshotPath: '', - isScreenshotProtectionOn: true, - wasScreenshotTaken: false, - isScreenRecording: true, - ), - ); + controller.add(ScreenshotSnapshot( + screenshotPath: '', + isScreenshotProtectionOn: true, + wasScreenshotTaken: false, + isScreenRecording: true, + )); await Future.delayed(Duration.zero); expect(started, hasLength(1)); @@ -755,58 +723,50 @@ void main() { noScreenshot.startCallbacks(); // First: recording starts - controller.add( - ScreenshotSnapshot( - screenshotPath: '', - isScreenshotProtectionOn: true, - wasScreenshotTaken: false, - isScreenRecording: true, - ), - ); + controller.add(ScreenshotSnapshot( + screenshotPath: '', + isScreenshotProtectionOn: true, + wasScreenshotTaken: false, + isScreenRecording: true, + )); await Future.delayed(Duration.zero); // Then: recording stops - controller.add( - ScreenshotSnapshot( - screenshotPath: '', - isScreenshotProtectionOn: true, - wasScreenshotTaken: false, - isScreenRecording: false, - ), - ); + controller.add(ScreenshotSnapshot( + screenshotPath: '', + isScreenshotProtectionOn: true, + wasScreenshotTaken: false, + isScreenRecording: false, + )); await Future.delayed(Duration.zero); expect(stopped, hasLength(1)); expect(stopped.first.isScreenRecording, false); }); - test( - 'removeAllCallbacks clears all callbacks and stops subscription', - () async { - final detected = []; - noScreenshot.onScreenshotDetected = detected.add; - noScreenshot.startCallbacks(); - expect(noScreenshot.hasActiveCallbacks, true); + test('removeAllCallbacks clears all callbacks and stops subscription', + () async { + final detected = []; + noScreenshot.onScreenshotDetected = detected.add; + noScreenshot.startCallbacks(); + expect(noScreenshot.hasActiveCallbacks, true); - noScreenshot.removeAllCallbacks(); - expect(noScreenshot.hasActiveCallbacks, false); - expect(noScreenshot.onScreenshotDetected, isNull); - expect(noScreenshot.onScreenRecordingStarted, isNull); - expect(noScreenshot.onScreenRecordingStopped, isNull); + noScreenshot.removeAllCallbacks(); + expect(noScreenshot.hasActiveCallbacks, false); + expect(noScreenshot.onScreenshotDetected, isNull); + expect(noScreenshot.onScreenRecordingStarted, isNull); + expect(noScreenshot.onScreenRecordingStopped, isNull); - // Events after removal should not fire - controller.add( - ScreenshotSnapshot( - screenshotPath: '/path', - isScreenshotProtectionOn: true, - wasScreenshotTaken: true, - ), - ); - await Future.delayed(Duration.zero); + // Events after removal should not fire + controller.add(ScreenshotSnapshot( + screenshotPath: '/path', + isScreenshotProtectionOn: true, + wasScreenshotTaken: true, + )); + await Future.delayed(Duration.zero); - expect(detected, isEmpty); - }, - ); + expect(detected, isEmpty); + }); test('hasActiveCallbacks reflects subscription state', () { expect(noScreenshot.hasActiveCallbacks, false); diff --git a/no_screenshot/test/no_screenshot_platform_interface_test.dart b/no_screenshot/test/no_screenshot_platform_interface_test.dart index a57e0b9..a8e4908 100644 --- a/no_screenshot/test/no_screenshot_platform_interface_test.dart +++ b/no_screenshot/test/no_screenshot_platform_interface_test.dart @@ -84,10 +84,8 @@ void main() { group('NoScreenshotPlatform', () { test('default instance should be MethodChannelNoScreenshot', () { - expect( - NoScreenshotPlatform.instance, - isInstanceOf(), - ); + expect(NoScreenshotPlatform.instance, + isInstanceOf()); }); test('screenshotOff should return true when called', () async { @@ -102,207 +100,160 @@ void main() { expect(await platform.toggleScreenshot(), isTrue); }); + test('screenshotStream should not throw UnimplementedError when accessed', + () { + expect(() => platform.screenshotStream, isNot(throwsUnimplementedError)); + }); test( - 'screenshotStream should not throw UnimplementedError when accessed', - () { - expect( - () => platform.screenshotStream, - isNot(throwsUnimplementedError), - ); - }, - ); - test( - 'startScreenshotListening should not throw UnimplementedError when called', - () async { - expect(platform.startScreenshotListening(), completes); - }, - ); + 'startScreenshotListening should not throw UnimplementedError when called', + () async { + expect(platform.startScreenshotListening(), completes); + }); test( - 'stopScreenshotListening should not throw UnimplementedError when called', - () async { - expect(platform.stopScreenshotListening(), completes); - }, - ); + 'stopScreenshotListening should not throw UnimplementedError when called', + () async { + expect(platform.stopScreenshotListening(), completes); + }); test('toggleScreenshotWithImage should return true when called', () async { expect(await platform.toggleScreenshotWithImage(), isTrue); }); test( - 'base NoScreenshotPlatform.toggleScreenshotWithImage() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.toggleScreenshotWithImage(), - throwsUnimplementedError, - ); - }, - ); + 'base NoScreenshotPlatform.toggleScreenshotWithImage() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.toggleScreenshotWithImage(), + throwsUnimplementedError); + }); test('toggleScreenshotWithBlur should return true when called', () async { expect(await platform.toggleScreenshotWithBlur(), isTrue); }); test( - 'base NoScreenshotPlatform.toggleScreenshotWithBlur() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.toggleScreenshotWithBlur(), - throwsUnimplementedError, - ); - }, - ); + 'base NoScreenshotPlatform.toggleScreenshotWithBlur() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.toggleScreenshotWithBlur(), + throwsUnimplementedError); + }); test('toggleScreenshotWithColor should return true when called', () async { expect(await platform.toggleScreenshotWithColor(), isTrue); }); test( - 'base NoScreenshotPlatform.toggleScreenshotWithColor() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.toggleScreenshotWithColor(), - throwsUnimplementedError, - ); - }, - ); + 'base NoScreenshotPlatform.toggleScreenshotWithColor() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.toggleScreenshotWithColor(), + throwsUnimplementedError); + }); test('screenshotWithImage should return true when called', () async { expect(await platform.screenshotWithImage(), isTrue); }); test( - 'base NoScreenshotPlatform.screenshotWithImage() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.screenshotWithImage(), - throwsUnimplementedError, - ); - }, - ); + 'base NoScreenshotPlatform.screenshotWithImage() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect( + () => basePlatform.screenshotWithImage(), throwsUnimplementedError); + }); test('screenshotWithBlur should return true when called', () async { expect(await platform.screenshotWithBlur(), isTrue); }); test( - 'base NoScreenshotPlatform.screenshotWithBlur() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.screenshotWithBlur(), - throwsUnimplementedError, - ); - }, - ); + 'base NoScreenshotPlatform.screenshotWithBlur() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.screenshotWithBlur(), throwsUnimplementedError); + }); test('screenshotWithColor should return true when called', () async { expect(await platform.screenshotWithColor(), isTrue); }); test( - 'base NoScreenshotPlatform.screenshotWithColor() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.screenshotWithColor(), - throwsUnimplementedError, - ); - }, - ); + 'base NoScreenshotPlatform.screenshotWithColor() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect( + () => basePlatform.screenshotWithColor(), throwsUnimplementedError); + }); + + test('base NoScreenshotPlatform.screenshotOff() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.screenshotOff(), throwsUnimplementedError); + }); + + test('base NoScreenshotPlatform.screenshotOn() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.screenshotOn(), throwsUnimplementedError); + }); test( - 'base NoScreenshotPlatform.screenshotOff() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect(() => basePlatform.screenshotOff(), throwsUnimplementedError); - }, - ); + 'base NoScreenshotPlatform.toggleScreenshot() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.toggleScreenshot(), throwsUnimplementedError); + }); + + test('base NoScreenshotPlatform.screenshotStream throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.screenshotStream, throwsUnimplementedError); + }); test( - 'base NoScreenshotPlatform.screenshotOn() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect(() => basePlatform.screenshotOn(), throwsUnimplementedError); - }, - ); + 'base NoScreenshotPlatform.startScreenshotListening() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.startScreenshotListening(), + throwsUnimplementedError); + }); test( - 'base NoScreenshotPlatform.toggleScreenshot() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect(() => basePlatform.toggleScreenshot(), throwsUnimplementedError); - }, - ); + 'base NoScreenshotPlatform.stopScreenshotListening() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.stopScreenshotListening(), + throwsUnimplementedError); + }); test( - 'base NoScreenshotPlatform.screenshotStream throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect(() => basePlatform.screenshotStream, throwsUnimplementedError); - }, - ); + 'startScreenRecordingListening should not throw UnimplementedError when called', + () async { + expect(platform.startScreenRecordingListening(), completes); + }); test( - 'base NoScreenshotPlatform.startScreenshotListening() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.startScreenshotListening(), - throwsUnimplementedError, - ); - }, - ); + 'stopScreenRecordingListening should not throw UnimplementedError when called', + () async { + expect(platform.stopScreenRecordingListening(), completes); + }); test( - 'base NoScreenshotPlatform.stopScreenshotListening() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.stopScreenshotListening(), - throwsUnimplementedError, - ); - }, - ); + 'base NoScreenshotPlatform.startScreenRecordingListening() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.startScreenRecordingListening(), + throwsUnimplementedError); + }); test( - 'startScreenRecordingListening should not throw UnimplementedError when called', - () async { - expect(platform.startScreenRecordingListening(), completes); - }, - ); - - test( - 'stopScreenRecordingListening should not throw UnimplementedError when called', - () async { - expect(platform.stopScreenRecordingListening(), completes); - }, - ); - - test( - 'base NoScreenshotPlatform.startScreenRecordingListening() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.startScreenRecordingListening(), - throwsUnimplementedError, - ); - }, - ); - - test( - 'base NoScreenshotPlatform.stopScreenRecordingListening() throws UnimplementedError', - () { - final basePlatform = BaseNoScreenshotPlatform(); - expect( - () => basePlatform.stopScreenRecordingListening(), - throwsUnimplementedError, - ); - }, - ); + 'base NoScreenshotPlatform.stopScreenRecordingListening() throws UnimplementedError', + () { + final basePlatform = BaseNoScreenshotPlatform(); + expect(() => basePlatform.stopScreenRecordingListening(), + throwsUnimplementedError); + }); }); } diff --git a/no_screenshot/test/no_screenshot_test.dart b/no_screenshot/test/no_screenshot_test.dart index e4f7d58..9d74bfe 100644 --- a/no_screenshot/test/no_screenshot_test.dart +++ b/no_screenshot/test/no_screenshot_test.dart @@ -115,10 +115,8 @@ void main() { }); test('screenshotStream', () async { - expect( - NoScreenshot.instance.screenshotStream, - isInstanceOf>(), - ); + expect(NoScreenshot.instance.screenshotStream, + isInstanceOf>()); }); test('startScreenshotListening', () async { expect(NoScreenshot.instance.startScreenshotListening(), completes); @@ -138,9 +136,8 @@ void main() { test('toggleScreenshotWithBlur with custom radius', () async { expect( - await NoScreenshot.instance.toggleScreenshotWithBlur(blurRadius: 50.0), - true, - ); + await NoScreenshot.instance.toggleScreenshotWithBlur(blurRadius: 50.0), + true); }); test('toggleScreenshotWithColor', () async { @@ -149,9 +146,9 @@ void main() { test('toggleScreenshotWithColor with custom color', () async { expect( - await NoScreenshot.instance.toggleScreenshotWithColor(color: 0xFFFF0000), - true, - ); + await NoScreenshot.instance + .toggleScreenshotWithColor(color: 0xFFFF0000), + true); }); test('screenshotWithImage', () async { @@ -164,9 +161,7 @@ void main() { test('screenshotWithBlur with custom radius', () async { expect( - await NoScreenshot.instance.screenshotWithBlur(blurRadius: 50.0), - true, - ); + await NoScreenshot.instance.screenshotWithBlur(blurRadius: 50.0), true); }); test('screenshotWithColor', () async { @@ -174,10 +169,8 @@ void main() { }); test('screenshotWithColor with custom color', () async { - expect( - await NoScreenshot.instance.screenshotWithColor(color: 0xFFFF0000), - true, - ); + expect(await NoScreenshot.instance.screenshotWithColor(color: 0xFFFF0000), + true); }); test('NoScreenshot equality operator', () { diff --git a/no_screenshot/test/secure_navigator_observer_test.dart b/no_screenshot/test/secure_navigator_observer_test.dart index 61862d8..85c93cb 100644 --- a/no_screenshot/test/secure_navigator_observer_test.dart +++ b/no_screenshot/test/secure_navigator_observer_test.dart @@ -132,7 +132,9 @@ void main() { test('didPop applies policy for previous route', () async { final observer = SecureNavigatorObserver( - policies: {'/home': const SecureRouteConfig(mode: OverlayMode.none)}, + policies: { + '/home': const SecureRouteConfig(mode: OverlayMode.none), + }, ); observer.didPop(_fakeRoute('/payment'), _fakeRoute('/home')); @@ -143,24 +145,22 @@ void main() { test('didReplace applies policy for new route', () async { final observer = SecureNavigatorObserver( policies: { - '/profile': const SecureRouteConfig( - mode: OverlayMode.blur, - blurRadius: 50.0, - ), + '/profile': + const SecureRouteConfig(mode: OverlayMode.blur, blurRadius: 50.0), }, ); observer.didReplace( - newRoute: _fakeRoute('/profile'), - oldRoute: _fakeRoute('/home'), - ); + newRoute: _fakeRoute('/profile'), oldRoute: _fakeRoute('/home')); await Future.delayed(Duration.zero); expect(fakePlatform.calls, contains('screenshotWithBlur(50.0)')); }); test('didRemove applies policy for previous route', () async { final observer = SecureNavigatorObserver( - policies: {'/home': const SecureRouteConfig(mode: OverlayMode.none)}, + policies: { + '/home': const SecureRouteConfig(mode: OverlayMode.none), + }, ); observer.didRemove(_fakeRoute('/payment'), _fakeRoute('/home')); @@ -232,9 +232,7 @@ void main() { observer.didPush(_fakeRoute('/branded'), null); await Future.delayed(Duration.zero); expect( - fakePlatform.calls, - contains('screenshotWithColor(${0xFF2196F3})'), - ); + fakePlatform.calls, contains('screenshotWithColor(${0xFF2196F3})')); }); }); } diff --git a/no_screenshot/test/secure_widget_test.dart b/no_screenshot/test/secure_widget_test.dart index 5dcc6fd..76ede81 100644 --- a/no_screenshot/test/secure_widget_test.dart +++ b/no_screenshot/test/secure_widget_test.dart @@ -85,14 +85,15 @@ void main() { }); testWidgets('default mode is OverlayMode.secure', (tester) async { - await tester.pumpWidget(const SecureWidget(child: SizedBox())); + await tester.pumpWidget( + const SecureWidget(child: SizedBox()), + ); await tester.pump(); expect(fakePlatform.calls, contains('screenshotOff')); }); - testWidgets('initState calls screenshotOff for OverlayMode.secure', ( - tester, - ) async { + testWidgets('initState calls screenshotOff for OverlayMode.secure', + (tester) async { await tester.pumpWidget( const SecureWidget(mode: OverlayMode.secure, child: SizedBox()), ); @@ -100,9 +101,8 @@ void main() { expect(fakePlatform.calls, contains('screenshotOff')); }); - testWidgets('initState calls screenshotWithBlur for OverlayMode.blur', ( - tester, - ) async { + testWidgets('initState calls screenshotWithBlur for OverlayMode.blur', + (tester) async { await tester.pumpWidget( const SecureWidget(mode: OverlayMode.blur, child: SizedBox()), ); @@ -110,9 +110,8 @@ void main() { expect(fakePlatform.calls, contains('screenshotWithBlur(30.0)')); }); - testWidgets('initState calls screenshotWithColor for OverlayMode.color', ( - tester, - ) async { + testWidgets('initState calls screenshotWithColor for OverlayMode.color', + (tester) async { await tester.pumpWidget( const SecureWidget(mode: OverlayMode.color, child: SizedBox()), ); @@ -120,9 +119,8 @@ void main() { expect(fakePlatform.calls, contains('screenshotWithColor(4278190080)')); }); - testWidgets('initState calls screenshotWithImage for OverlayMode.image', ( - tester, - ) async { + testWidgets('initState calls screenshotWithImage for OverlayMode.image', + (tester) async { await tester.pumpWidget( const SecureWidget(mode: OverlayMode.image, child: SizedBox()), ); @@ -130,9 +128,8 @@ void main() { expect(fakePlatform.calls, contains('screenshotWithImage')); }); - testWidgets('initState calls screenshotOn for OverlayMode.none', ( - tester, - ) async { + testWidgets('initState calls screenshotOn for OverlayMode.none', + (tester) async { await tester.pumpWidget( const SecureWidget(mode: OverlayMode.none, child: SizedBox()), ); @@ -141,7 +138,9 @@ void main() { }); testWidgets('dispose calls screenshotOn', (tester) async { - await tester.pumpWidget(const SecureWidget(child: SizedBox())); + await tester.pumpWidget( + const SecureWidget(child: SizedBox()), + ); await tester.pump(); fakePlatform.calls.clear(); @@ -165,25 +164,18 @@ void main() { expect(fakePlatform.calls, contains('screenshotWithBlur(30.0)')); }); - testWidgets('didUpdateWidget re-applies when blurRadius changes', ( - tester, - ) async { + testWidgets('didUpdateWidget re-applies when blurRadius changes', + (tester) async { await tester.pumpWidget( const SecureWidget( - mode: OverlayMode.blur, - blurRadius: 30.0, - child: SizedBox(), - ), + mode: OverlayMode.blur, blurRadius: 30.0, child: SizedBox()), ); await tester.pump(); fakePlatform.calls.clear(); await tester.pumpWidget( const SecureWidget( - mode: OverlayMode.blur, - blurRadius: 50.0, - child: SizedBox(), - ), + mode: OverlayMode.blur, blurRadius: 50.0, child: SizedBox()), ); await tester.pump(); expect(fakePlatform.calls, contains('screenshotWithBlur(50.0)')); @@ -198,18 +190,14 @@ void main() { await tester.pumpWidget( const SecureWidget( - mode: OverlayMode.color, - color: 0xFFFF0000, - child: SizedBox(), - ), + mode: OverlayMode.color, color: 0xFFFF0000, child: SizedBox()), ); await tester.pump(); expect(fakePlatform.calls, contains('screenshotWithColor(4294901760)')); }); - testWidgets('didUpdateWidget does not re-apply when nothing changes', ( - tester, - ) async { + testWidgets('didUpdateWidget does not re-apply when nothing changes', + (tester) async { await tester.pumpWidget( const SecureWidget(mode: OverlayMode.secure, child: SizedBox()), );