update deps
This commit is contained in:
parent
7c253994e4
commit
793b7f0562
20 changed files with 440 additions and 695 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class NumericFingerprintGenerator implements FingerprintGenerator {
|
|||
final sortedIdentityKeys = [...identityKeys]..sort(identityKeyComparator);
|
||||
|
||||
final keys = <int>[];
|
||||
sortedIdentityKeys.forEach((IdentityKey key) {
|
||||
sortedIdentityKeys.forEach((key) {
|
||||
final publicKeyBytes = key.publicKey.serialize();
|
||||
keys.addAll(publicKeyBytes.toList());
|
||||
});
|
||||
|
|
|
|||
|
|
@ -62,9 +62,6 @@ class LogicalFingerprint extends $pb.GeneratedMessage {
|
|||
@override
|
||||
LogicalFingerprint createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<LogicalFingerprint> createRepeated() =>
|
||||
$pb.PbList<LogicalFingerprint>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static LogicalFingerprint getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<LogicalFingerprint>(create);
|
||||
|
|
@ -167,9 +164,6 @@ class CombinedFingerprints extends $pb.GeneratedMessage {
|
|||
@override
|
||||
CombinedFingerprints createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<CombinedFingerprints> createRepeated() =>
|
||||
$pb.PbList<CombinedFingerprints>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static CombinedFingerprints getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<CombinedFingerprints>(create);
|
||||
|
|
|
|||
|
|
@ -80,9 +80,6 @@ class SessionStructureChainChainKey extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SessionStructureChainChainKey createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SessionStructureChainChainKey> createRepeated() =>
|
||||
$pb.PbList<SessionStructureChainChainKey>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SessionStructureChainChainKey getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SessionStructureChainChainKey>(create);
|
||||
|
|
@ -214,9 +211,6 @@ class SessionStructureChainMessageKey extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SessionStructureChainMessageKey createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SessionStructureChainMessageKey> createRepeated() =>
|
||||
$pb.PbList<SessionStructureChainMessageKey>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SessionStructureChainMessageKey getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SessionStructureChainMessageKey>(
|
||||
|
|
@ -378,9 +372,6 @@ class SessionStructureChain extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SessionStructureChain createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SessionStructureChain> createRepeated() =>
|
||||
$pb.PbList<SessionStructureChain>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SessionStructureChain getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SessionStructureChain>(create);
|
||||
|
|
@ -565,9 +556,6 @@ class SessionStructurePendingKeyExchange extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SessionStructurePendingKeyExchange createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SessionStructurePendingKeyExchange> createRepeated() =>
|
||||
$pb.PbList<SessionStructurePendingKeyExchange>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SessionStructurePendingKeyExchange getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SessionStructurePendingKeyExchange>(
|
||||
|
|
@ -760,9 +748,6 @@ class SessionStructurePendingPreKey extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SessionStructurePendingPreKey createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SessionStructurePendingPreKey> createRepeated() =>
|
||||
$pb.PbList<SessionStructurePendingPreKey>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SessionStructurePendingPreKey getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SessionStructurePendingPreKey>(create);
|
||||
|
|
@ -1004,9 +989,6 @@ class SessionStructure extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SessionStructure createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SessionStructure> createRepeated() =>
|
||||
$pb.PbList<SessionStructure>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SessionStructure getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SessionStructure>(create);
|
||||
|
|
@ -1266,9 +1248,6 @@ class RecordStructure extends $pb.GeneratedMessage {
|
|||
@override
|
||||
RecordStructure createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<RecordStructure> createRepeated() =>
|
||||
$pb.PbList<RecordStructure>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static RecordStructure getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<RecordStructure>(create);
|
||||
|
|
@ -1379,9 +1358,6 @@ class PreKeyRecordStructure extends $pb.GeneratedMessage {
|
|||
@override
|
||||
PreKeyRecordStructure createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<PreKeyRecordStructure> createRepeated() =>
|
||||
$pb.PbList<PreKeyRecordStructure>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static PreKeyRecordStructure getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<PreKeyRecordStructure>(create);
|
||||
|
|
@ -1537,9 +1513,6 @@ class SignedPreKeyRecordStructure extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SignedPreKeyRecordStructure createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SignedPreKeyRecordStructure> createRepeated() =>
|
||||
$pb.PbList<SignedPreKeyRecordStructure>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SignedPreKeyRecordStructure getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SignedPreKeyRecordStructure>(create);
|
||||
|
|
@ -1690,9 +1663,6 @@ class IdentityKeyPairStructure extends $pb.GeneratedMessage {
|
|||
@override
|
||||
IdentityKeyPairStructure createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<IdentityKeyPairStructure> createRepeated() =>
|
||||
$pb.PbList<IdentityKeyPairStructure>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static IdentityKeyPairStructure getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<IdentityKeyPairStructure>(create);
|
||||
|
|
@ -1802,9 +1772,6 @@ class SenderKeyStateStructureSenderChainKey extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SenderKeyStateStructureSenderChainKey createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SenderKeyStateStructureSenderChainKey> createRepeated() =>
|
||||
$pb.PbList<SenderKeyStateStructureSenderChainKey>();
|
||||
|
||||
@$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<SenderKeyStateStructureSenderMessageKey> createRepeated() =>
|
||||
$pb.PbList<SenderKeyStateStructureSenderMessageKey>();
|
||||
|
||||
@$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<SenderKeyStateStructureSenderSigningKey> createRepeated() =>
|
||||
$pb.PbList<SenderKeyStateStructureSenderSigningKey>();
|
||||
|
||||
@$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<SenderKeyStateStructure> createRepeated() =>
|
||||
$pb.PbList<SenderKeyStateStructure>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SenderKeyStateStructure getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SenderKeyStateStructure>(create);
|
||||
|
|
@ -2288,9 +2246,6 @@ class SenderKeyRecordStructure extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SenderKeyRecordStructure createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SenderKeyRecordStructure> createRepeated() =>
|
||||
$pb.PbList<SenderKeyRecordStructure>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SenderKeyRecordStructure getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SenderKeyRecordStructure>(create);
|
||||
|
|
|
|||
|
|
@ -95,9 +95,6 @@ class SignalMessage extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SignalMessage createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SignalMessage> createRepeated() =>
|
||||
$pb.PbList<SignalMessage>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SignalMessage getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SignalMessage>(create);
|
||||
|
|
@ -275,9 +272,6 @@ class PreKeySignalMessage extends $pb.GeneratedMessage {
|
|||
@override
|
||||
PreKeySignalMessage createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<PreKeySignalMessage> createRepeated() =>
|
||||
$pb.PbList<PreKeySignalMessage>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static PreKeySignalMessage getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<PreKeySignalMessage>(create);
|
||||
|
|
@ -473,9 +467,6 @@ class KeyExchangeMessage extends $pb.GeneratedMessage {
|
|||
@override
|
||||
KeyExchangeMessage createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<KeyExchangeMessage> createRepeated() =>
|
||||
$pb.PbList<KeyExchangeMessage>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static KeyExchangeMessage getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<KeyExchangeMessage>(create);
|
||||
|
|
@ -632,9 +623,6 @@ class SenderKeyMessage extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SenderKeyMessage createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SenderKeyMessage> createRepeated() =>
|
||||
$pb.PbList<SenderKeyMessage>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SenderKeyMessage getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SenderKeyMessage>(create);
|
||||
|
|
@ -779,9 +767,6 @@ class SenderKeyDistributionMessage extends $pb.GeneratedMessage {
|
|||
@override
|
||||
SenderKeyDistributionMessage createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<SenderKeyDistributionMessage> createRepeated() =>
|
||||
$pb.PbList<SenderKeyDistributionMessage>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static SenderKeyDistributionMessage getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<SenderKeyDistributionMessage>(create);
|
||||
|
|
@ -918,9 +903,6 @@ class DeviceConsistencyCodeMessage extends $pb.GeneratedMessage {
|
|||
@override
|
||||
DeviceConsistencyCodeMessage createEmptyInstance() => create();
|
||||
|
||||
static $pb.PbList<DeviceConsistencyCodeMessage> createRepeated() =>
|
||||
$pb.PbList<DeviceConsistencyCodeMessage>();
|
||||
|
||||
@$core.pragma('dart2js:noInline')
|
||||
static DeviceConsistencyCodeMessage getDefault() => _defaultInstance ??=
|
||||
$pb.GeneratedMessage.$_defaultFor<DeviceConsistencyCodeMessage>(create);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<Int> { 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<Int> ?: 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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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._();
|
||||
|
|
|
|||
|
|
@ -19,18 +19,15 @@ class MethodChannelNoScreenshot extends NoScreenshotPlatform {
|
|||
|
||||
@override
|
||||
Stream<ScreenshotSnapshot> get screenshotStream {
|
||||
_cachedStream ??= eventChannel.receiveBroadcastStream().map(
|
||||
(event) =>
|
||||
ScreenshotSnapshot.fromMap(jsonDecode(event) as Map<String, dynamic>),
|
||||
);
|
||||
_cachedStream ??= eventChannel.receiveBroadcastStream().map((event) =>
|
||||
ScreenshotSnapshot.fromMap(jsonDecode(event) as Map<String, dynamic>));
|
||||
return _cachedStream!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> toggleScreenshot() async {
|
||||
final result = await methodChannel.invokeMethod<bool>(
|
||||
toggleScreenShotConst,
|
||||
);
|
||||
final result =
|
||||
await methodChannel.invokeMethod<bool>(toggleScreenShotConst);
|
||||
return result ?? false;
|
||||
}
|
||||
|
||||
|
|
@ -54,17 +51,15 @@ class MethodChannelNoScreenshot extends NoScreenshotPlatform {
|
|||
|
||||
@override
|
||||
Future<bool> toggleScreenshotWithBlur({double blurRadius = 30.0}) async {
|
||||
final result = await methodChannel.invokeMethod<bool>(screenSetBlur, {
|
||||
'radius': blurRadius,
|
||||
});
|
||||
final result = await methodChannel
|
||||
.invokeMethod<bool>(screenSetBlur, {'radius': blurRadius});
|
||||
return result ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> toggleScreenshotWithColor({int color = 0xFF000000}) async {
|
||||
final result = await methodChannel.invokeMethod<bool>(screenSetColor, {
|
||||
'color': color,
|
||||
});
|
||||
final result = await methodChannel
|
||||
.invokeMethod<bool>(screenSetColor, {'color': color});
|
||||
return result ?? false;
|
||||
}
|
||||
|
||||
|
|
@ -76,17 +71,15 @@ class MethodChannelNoScreenshot extends NoScreenshotPlatform {
|
|||
|
||||
@override
|
||||
Future<bool> screenshotWithBlur({double blurRadius = 30.0}) async {
|
||||
final result = await methodChannel.invokeMethod<bool>(screenEnableBlur, {
|
||||
'radius': blurRadius,
|
||||
});
|
||||
final result = await methodChannel
|
||||
.invokeMethod<bool>(screenEnableBlur, {'radius': blurRadius});
|
||||
return result ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> screenshotWithColor({int color = 0xFF000000}) async {
|
||||
final result = await methodChannel.invokeMethod<bool>(screenEnableColor, {
|
||||
'color': color,
|
||||
});
|
||||
final result = await methodChannel
|
||||
.invokeMethod<bool>(screenEnableColor, {'color': color});
|
||||
return result ?? false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,20 +43,17 @@ abstract class NoScreenshotPlatform extends PlatformInterface {
|
|||
/// throw `UnmimplementedError` if not implement
|
||||
Future<bool> toggleScreenshotWithImage() {
|
||||
throw UnimplementedError(
|
||||
'toggleScreenshotWithImage() has not been implemented.',
|
||||
);
|
||||
'toggleScreenshotWithImage() has not been implemented.');
|
||||
}
|
||||
|
||||
Future<bool> toggleScreenshotWithBlur({double blurRadius = 30.0}) {
|
||||
throw UnimplementedError(
|
||||
'toggleScreenshotWithBlur() has not been implemented.',
|
||||
);
|
||||
'toggleScreenshotWithBlur() has not been implemented.');
|
||||
}
|
||||
|
||||
Future<bool> 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<void> startScreenshotListening() {
|
||||
throw UnimplementedError(
|
||||
'startScreenshotListening has not been implemented.',
|
||||
);
|
||||
'startScreenshotListening has not been implemented.');
|
||||
}
|
||||
|
||||
/// Stop listening to screenshot activities
|
||||
Future<void> stopScreenshotListening() {
|
||||
throw UnimplementedError(
|
||||
'stopScreenshotListening has not been implemented.',
|
||||
);
|
||||
'stopScreenshotListening has not been implemented.');
|
||||
}
|
||||
|
||||
/// Start listening to screen recording activities
|
||||
Future<void> startScreenRecordingListening() {
|
||||
throw UnimplementedError(
|
||||
'startScreenRecordingListening has not been implemented.',
|
||||
);
|
||||
'startScreenRecordingListening has not been implemented.');
|
||||
}
|
||||
|
||||
/// Stop listening to screen recording activities
|
||||
Future<void> stopScreenRecordingListening() {
|
||||
throw UnimplementedError(
|
||||
'stopScreenRecordingListening has not been implemented.',
|
||||
);
|
||||
'stopScreenRecordingListening has not been implemented.');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,13 +138,11 @@ class NoScreenshotWeb extends NoScreenshotPlatform {
|
|||
}
|
||||
|
||||
void _emitState({bool wasScreenshotTaken = false}) {
|
||||
_controller.add(
|
||||
ScreenshotSnapshot(
|
||||
_controller.add(ScreenshotSnapshot(
|
||||
screenshotPath: '',
|
||||
isScreenshotProtectionOn: _isProtectionOn,
|
||||
wasScreenshotTaken: wasScreenshotTaken,
|
||||
),
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
// ── Context menu blocker ───────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -73,10 +73,7 @@ class SecureNavigatorObserver extends NavigatorObserver {
|
|||
void _applyPolicyForRoute(Route<dynamic>? 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -133,8 +133,7 @@ void main() {
|
|||
expect(result, expected);
|
||||
});
|
||||
|
||||
test(
|
||||
'toggleScreenshotWithBlur returns false when channel returns null',
|
||||
test('toggleScreenshotWithBlur returns false when channel returns null',
|
||||
() async {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
|
||||
|
|
@ -143,8 +142,7 @@ void main() {
|
|||
|
||||
final result = await platform.toggleScreenshotWithBlur();
|
||||
expect(result, false);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('toggleScreenshotWithColor', () async {
|
||||
const bool expected = true;
|
||||
|
|
@ -172,14 +170,12 @@ void main() {
|
|||
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',
|
||||
test('toggleScreenshotWithColor returns false when channel returns null',
|
||||
() async {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
|
||||
|
|
@ -188,11 +184,9 @@ void main() {
|
|||
|
||||
final result = await platform.toggleScreenshotWithColor();
|
||||
expect(result, false);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'toggleScreenshotWithImage returns false when channel returns null',
|
||||
test('toggleScreenshotWithImage returns false when channel returns null',
|
||||
() async {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
|
||||
|
|
@ -201,8 +195,7 @@ void main() {
|
|||
|
||||
final result = await platform.toggleScreenshotWithImage();
|
||||
expect(result, false);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('screenshotOn returns false when channel returns null', () async {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
|
|
@ -248,8 +241,7 @@ void main() {
|
|||
expect(result, expected);
|
||||
});
|
||||
|
||||
test(
|
||||
'screenshotWithImage returns false when channel returns null',
|
||||
test('screenshotWithImage returns false when channel returns null',
|
||||
() async {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
|
||||
|
|
@ -258,8 +250,7 @@ void main() {
|
|||
|
||||
final result = await platform.screenshotWithImage();
|
||||
expect(result, false);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('screenshotWithBlur', () async {
|
||||
const bool expected = true;
|
||||
|
|
@ -291,8 +282,7 @@ void main() {
|
|||
expect(result, expected);
|
||||
});
|
||||
|
||||
test(
|
||||
'screenshotWithBlur returns false when channel returns null',
|
||||
test('screenshotWithBlur returns false when channel returns null',
|
||||
() async {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
|
||||
|
|
@ -301,8 +291,7 @@ void main() {
|
|||
|
||||
final result = await platform.screenshotWithBlur();
|
||||
expect(result, false);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('screenshotWithColor', () async {
|
||||
const bool expected = true;
|
||||
|
|
@ -334,8 +323,7 @@ void main() {
|
|||
expect(result, expected);
|
||||
});
|
||||
|
||||
test(
|
||||
'screenshotWithColor returns false when channel returns null',
|
||||
test('screenshotWithColor returns false when channel returns null',
|
||||
() async {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
|
||||
|
|
@ -344,8 +332,7 @@ void main() {
|
|||
|
||||
final result = await platform.screenshotWithColor();
|
||||
expect(result, false);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('startScreenRecordingListening', () async {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
|
|
@ -373,8 +360,7 @@ void main() {
|
|||
expect(true, true);
|
||||
});
|
||||
|
||||
test(
|
||||
'screenshotStream returns a stream that emits ScreenshotSnapshot',
|
||||
test('screenshotStream returns a stream that emits ScreenshotSnapshot',
|
||||
() async {
|
||||
final snapshotMap = {
|
||||
'screenshot_path': '/test/path',
|
||||
|
|
@ -388,14 +374,11 @@ void main() {
|
|||
|
||||
// Mock the event channel by handling the underlying method channel
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockStreamHandler(
|
||||
platform.eventChannel,
|
||||
MockStreamHandler.inline(
|
||||
.setMockStreamHandler(platform.eventChannel, MockStreamHandler.inline(
|
||||
onListen: (arguments, events) {
|
||||
events.success(encoded);
|
||||
},
|
||||
),
|
||||
);
|
||||
));
|
||||
|
||||
final stream = platform.screenshotStream;
|
||||
final snapshot = await stream.first;
|
||||
|
|
@ -403,8 +386,7 @@ void main() {
|
|||
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',
|
||||
test('onScreenshotDetected fires when wasScreenshotTaken is true',
|
||||
() async {
|
||||
final detected = <ScreenshotSnapshot>[];
|
||||
noScreenshot.onScreenshotDetected = detected.add;
|
||||
noScreenshot.startCallbacks();
|
||||
|
||||
controller.add(
|
||||
ScreenshotSnapshot(
|
||||
controller.add(ScreenshotSnapshot(
|
||||
screenshotPath: '/path',
|
||||
isScreenshotProtectionOn: true,
|
||||
wasScreenshotTaken: true,
|
||||
),
|
||||
);
|
||||
));
|
||||
await Future.delayed(Duration.zero);
|
||||
|
||||
expect(detected, hasLength(1));
|
||||
expect(detected.first.wasScreenshotTaken, true);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'onScreenshotDetected does NOT fire when wasScreenshotTaken is false',
|
||||
test('onScreenshotDetected does NOT fire when wasScreenshotTaken is false',
|
||||
() async {
|
||||
final detected = <ScreenshotSnapshot>[];
|
||||
noScreenshot.onScreenshotDetected = detected.add;
|
||||
noScreenshot.startCallbacks();
|
||||
|
||||
controller.add(
|
||||
ScreenshotSnapshot(
|
||||
controller.add(ScreenshotSnapshot(
|
||||
screenshotPath: '',
|
||||
isScreenshotProtectionOn: true,
|
||||
wasScreenshotTaken: false,
|
||||
),
|
||||
);
|
||||
));
|
||||
await Future.delayed(Duration.zero);
|
||||
|
||||
expect(detected, isEmpty);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('onScreenRecordingStarted fires on false→true transition', () async {
|
||||
final started = <ScreenshotSnapshot>[];
|
||||
|
|
@ -735,14 +705,12 @@ void main() {
|
|||
noScreenshot.startCallbacks();
|
||||
|
||||
// Initial state: not recording → recording starts
|
||||
controller.add(
|
||||
ScreenshotSnapshot(
|
||||
controller.add(ScreenshotSnapshot(
|
||||
screenshotPath: '',
|
||||
isScreenshotProtectionOn: true,
|
||||
wasScreenshotTaken: false,
|
||||
isScreenRecording: true,
|
||||
),
|
||||
);
|
||||
));
|
||||
await Future.delayed(Duration.zero);
|
||||
|
||||
expect(started, hasLength(1));
|
||||
|
|
@ -755,33 +723,28 @@ void main() {
|
|||
noScreenshot.startCallbacks();
|
||||
|
||||
// First: recording starts
|
||||
controller.add(
|
||||
ScreenshotSnapshot(
|
||||
controller.add(ScreenshotSnapshot(
|
||||
screenshotPath: '',
|
||||
isScreenshotProtectionOn: true,
|
||||
wasScreenshotTaken: false,
|
||||
isScreenRecording: true,
|
||||
),
|
||||
);
|
||||
));
|
||||
await Future.delayed(Duration.zero);
|
||||
|
||||
// Then: recording stops
|
||||
controller.add(
|
||||
ScreenshotSnapshot(
|
||||
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',
|
||||
test('removeAllCallbacks clears all callbacks and stops subscription',
|
||||
() async {
|
||||
final detected = <ScreenshotSnapshot>[];
|
||||
noScreenshot.onScreenshotDetected = detected.add;
|
||||
|
|
@ -795,18 +758,15 @@ void main() {
|
|||
expect(noScreenshot.onScreenRecordingStopped, isNull);
|
||||
|
||||
// Events after removal should not fire
|
||||
controller.add(
|
||||
ScreenshotSnapshot(
|
||||
controller.add(ScreenshotSnapshot(
|
||||
screenshotPath: '/path',
|
||||
isScreenshotProtectionOn: true,
|
||||
wasScreenshotTaken: true,
|
||||
),
|
||||
);
|
||||
));
|
||||
await Future.delayed(Duration.zero);
|
||||
|
||||
expect(detected, isEmpty);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('hasActiveCallbacks reflects subscription state', () {
|
||||
expect(noScreenshot.hasActiveCallbacks, false);
|
||||
|
|
|
|||
|
|
@ -84,10 +84,8 @@ void main() {
|
|||
|
||||
group('NoScreenshotPlatform', () {
|
||||
test('default instance should be MethodChannelNoScreenshot', () {
|
||||
expect(
|
||||
NoScreenshotPlatform.instance,
|
||||
isInstanceOf<MethodChannelNoScreenshot>(),
|
||||
);
|
||||
expect(NoScreenshotPlatform.instance,
|
||||
isInstanceOf<MethodChannelNoScreenshot>());
|
||||
});
|
||||
|
||||
test('screenshotOff should return true when called', () async {
|
||||
|
|
@ -102,28 +100,21 @@ void main() {
|
|||
expect(await platform.toggleScreenshot(), isTrue);
|
||||
});
|
||||
|
||||
test(
|
||||
'screenshotStream should not throw UnimplementedError when accessed',
|
||||
test('screenshotStream should not throw UnimplementedError when accessed',
|
||||
() {
|
||||
expect(
|
||||
() => platform.screenshotStream,
|
||||
isNot(throwsUnimplementedError),
|
||||
);
|
||||
},
|
||||
);
|
||||
expect(() => platform.screenshotStream, isNot(throwsUnimplementedError));
|
||||
});
|
||||
test(
|
||||
'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);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('toggleScreenshotWithImage should return true when called', () async {
|
||||
expect(await platform.toggleScreenshotWithImage(), isTrue);
|
||||
|
|
@ -133,12 +124,9 @@ void main() {
|
|||
'base NoScreenshotPlatform.toggleScreenshotWithImage() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(
|
||||
() => basePlatform.toggleScreenshotWithImage(),
|
||||
throwsUnimplementedError,
|
||||
);
|
||||
},
|
||||
);
|
||||
expect(() => basePlatform.toggleScreenshotWithImage(),
|
||||
throwsUnimplementedError);
|
||||
});
|
||||
|
||||
test('toggleScreenshotWithBlur should return true when called', () async {
|
||||
expect(await platform.toggleScreenshotWithBlur(), isTrue);
|
||||
|
|
@ -148,12 +136,9 @@ void main() {
|
|||
'base NoScreenshotPlatform.toggleScreenshotWithBlur() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(
|
||||
() => basePlatform.toggleScreenshotWithBlur(),
|
||||
throwsUnimplementedError,
|
||||
);
|
||||
},
|
||||
);
|
||||
expect(() => basePlatform.toggleScreenshotWithBlur(),
|
||||
throwsUnimplementedError);
|
||||
});
|
||||
|
||||
test('toggleScreenshotWithColor should return true when called', () async {
|
||||
expect(await platform.toggleScreenshotWithColor(), isTrue);
|
||||
|
|
@ -163,12 +148,9 @@ void main() {
|
|||
'base NoScreenshotPlatform.toggleScreenshotWithColor() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(
|
||||
() => basePlatform.toggleScreenshotWithColor(),
|
||||
throwsUnimplementedError,
|
||||
);
|
||||
},
|
||||
);
|
||||
expect(() => basePlatform.toggleScreenshotWithColor(),
|
||||
throwsUnimplementedError);
|
||||
});
|
||||
|
||||
test('screenshotWithImage should return true when called', () async {
|
||||
expect(await platform.screenshotWithImage(), isTrue);
|
||||
|
|
@ -179,11 +161,8 @@ void main() {
|
|||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(
|
||||
() => basePlatform.screenshotWithImage(),
|
||||
throwsUnimplementedError,
|
||||
);
|
||||
},
|
||||
);
|
||||
() => basePlatform.screenshotWithImage(), throwsUnimplementedError);
|
||||
});
|
||||
|
||||
test('screenshotWithBlur should return true when called', () async {
|
||||
expect(await platform.screenshotWithBlur(), isTrue);
|
||||
|
|
@ -193,12 +172,8 @@ void main() {
|
|||
'base NoScreenshotPlatform.screenshotWithBlur() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(
|
||||
() => basePlatform.screenshotWithBlur(),
|
||||
throwsUnimplementedError,
|
||||
);
|
||||
},
|
||||
);
|
||||
expect(() => basePlatform.screenshotWithBlur(), throwsUnimplementedError);
|
||||
});
|
||||
|
||||
test('screenshotWithColor should return true when called', () async {
|
||||
expect(await platform.screenshotWithColor(), isTrue);
|
||||
|
|
@ -209,100 +184,76 @@ void main() {
|
|||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(
|
||||
() => basePlatform.screenshotWithColor(),
|
||||
throwsUnimplementedError,
|
||||
);
|
||||
},
|
||||
);
|
||||
() => basePlatform.screenshotWithColor(), throwsUnimplementedError);
|
||||
});
|
||||
|
||||
test(
|
||||
'base NoScreenshotPlatform.screenshotOff() throws UnimplementedError',
|
||||
test('base NoScreenshotPlatform.screenshotOff() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(() => basePlatform.screenshotOff(), throwsUnimplementedError);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'base NoScreenshotPlatform.screenshotOn() throws UnimplementedError',
|
||||
test('base NoScreenshotPlatform.screenshotOn() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(() => basePlatform.screenshotOn(), throwsUnimplementedError);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'base NoScreenshotPlatform.toggleScreenshot() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(() => basePlatform.toggleScreenshot(), throwsUnimplementedError);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'base NoScreenshotPlatform.screenshotStream throws UnimplementedError',
|
||||
test('base NoScreenshotPlatform.screenshotStream throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(() => basePlatform.screenshotStream, throwsUnimplementedError);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'base NoScreenshotPlatform.startScreenshotListening() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(
|
||||
() => basePlatform.startScreenshotListening(),
|
||||
throwsUnimplementedError,
|
||||
);
|
||||
},
|
||||
);
|
||||
expect(() => basePlatform.startScreenshotListening(),
|
||||
throwsUnimplementedError);
|
||||
});
|
||||
|
||||
test(
|
||||
'base NoScreenshotPlatform.stopScreenshotListening() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(
|
||||
() => basePlatform.stopScreenshotListening(),
|
||||
throwsUnimplementedError,
|
||||
);
|
||||
},
|
||||
);
|
||||
expect(() => basePlatform.stopScreenshotListening(),
|
||||
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,
|
||||
);
|
||||
},
|
||||
);
|
||||
expect(() => basePlatform.startScreenRecordingListening(),
|
||||
throwsUnimplementedError);
|
||||
});
|
||||
|
||||
test(
|
||||
'base NoScreenshotPlatform.stopScreenRecordingListening() throws UnimplementedError',
|
||||
() {
|
||||
final basePlatform = BaseNoScreenshotPlatform();
|
||||
expect(
|
||||
() => basePlatform.stopScreenRecordingListening(),
|
||||
throwsUnimplementedError,
|
||||
);
|
||||
},
|
||||
);
|
||||
expect(() => basePlatform.stopScreenRecordingListening(),
|
||||
throwsUnimplementedError);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,10 +115,8 @@ void main() {
|
|||
});
|
||||
|
||||
test('screenshotStream', () async {
|
||||
expect(
|
||||
NoScreenshot.instance.screenshotStream,
|
||||
isInstanceOf<Stream<ScreenshotSnapshot>>(),
|
||||
);
|
||||
expect(NoScreenshot.instance.screenshotStream,
|
||||
isInstanceOf<Stream<ScreenshotSnapshot>>());
|
||||
});
|
||||
test('startScreenshotListening', () async {
|
||||
expect(NoScreenshot.instance.startScreenshotListening(), completes);
|
||||
|
|
@ -139,8 +137,7 @@ void main() {
|
|||
test('toggleScreenshotWithBlur with custom radius', () async {
|
||||
expect(
|
||||
await NoScreenshot.instance.toggleScreenshotWithBlur(blurRadius: 50.0),
|
||||
true,
|
||||
);
|
||||
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', () {
|
||||
|
|
|
|||
|
|
@ -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<void>.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<void>.delayed(Duration.zero);
|
||||
expect(
|
||||
fakePlatform.calls,
|
||||
contains('screenshotWithColor(${0xFF2196F3})'),
|
||||
);
|
||||
fakePlatform.calls, contains('screenshotWithColor(${0xFF2196F3})'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue