diff --git a/.gitignore b/.gitignore
index 3b5517d..4e395b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,21 +1,46 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
.DS_Store
-.dart_tool/
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+# .vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
.packages
+.pub-cache/
.pub/
+/build/
-build/
+# Symbolication related
+app.*.symbols
-# IntelliJ
-*.iml
-.idea/workspace.xml
-.idea/tasks.xml
-.idea/gradle.xml
-.idea/assetWizardSettings.xml
-.idea/dictionaries
-.idea/libraries
-.idea/caches
+# Obfuscation related
+app.*.map.json
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
#Ignore thumbnails created by Windows
Thumbs.db
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 117351f..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index dc7311b..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/.idea/runConfigurations/example_lib_main_dart.xml b/.idea/runConfigurations/example_lib_main_dart.xml
deleted file mode 100644
index 5fd9159..0000000
--- a/.idea/runConfigurations/example_lib_main_dart.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index 25de80d..0000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1628727602623
-
-
- 1628727602623
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.metadata b/.metadata
deleted file mode 100644
index 9fc7ede..0000000
--- a/.metadata
+++ /dev/null
@@ -1,10 +0,0 @@
-# This file tracks properties of this Flutter project.
-# Used by Flutter tool to assess capabilities and perform upgrades etc.
-#
-# This file should be version controlled and should not be manually edited.
-
-version:
- revision: 0b8abb4724aa590dd0f429683339b1e045a1594d
- channel: stable
-
-project_type: plugin
diff --git a/android/src/main/kotlin/org/jezequel/secure_application/SecureApplicationPlugin.kt b/android/src/main/kotlin/org/jezequel/secure_application/SecureApplicationPlugin.kt
index 4f0b3ac..dea620c 100644
--- a/android/src/main/kotlin/org/jezequel/secure_application/SecureApplicationPlugin.kt
+++ b/android/src/main/kotlin/org/jezequel/secure_application/SecureApplicationPlugin.kt
@@ -50,7 +50,7 @@ public class SecureApplicationPlugin: FlutterPlugin, MethodCallHandler, Activity
}
- override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
+ override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
instance = SecureApplicationPlugin()
val channel = MethodChannel(flutterPluginBinding.binaryMessenger, "secure_application")
channel.setMethodCallHandler(instance)
@@ -78,18 +78,26 @@ public class SecureApplicationPlugin: FlutterPlugin, MethodCallHandler, Activity
}
}
- override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
- if (call.method == "secure") {
- activity?.window?.addFlags(LayoutParams.FLAG_SECURE)
- result.success(true)
- } else if (call.method == "open") {
- activity?.window?.clearFlags(LayoutParams.FLAG_SECURE)
- result.success(true)
- } else {
- result.success(true)
+ override fun onMethodCall(call: MethodCall, result: Result) {
+ when (call.method) {
+ "secure" -> {
+ activity?.window?.addFlags(LayoutParams.FLAG_SECURE)
+ result.success(true)
+ }
+ "open" -> {
+ activity?.window?.clearFlags(LayoutParams.FLAG_SECURE)
+ result.success(true)
+ }
+ "opacity" -> {
+ // Implementation available only on ios
+ result.success(true)
+ }
+ else -> {
+ result.notImplemented()
+ }
}
}
- override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
+ override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
}
}
diff --git a/example/ios/Podfile b/example/ios/Podfile
index 1e8c3c9..313ea4a 100644
--- a/example/ios/Podfile
+++ b/example/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
-# platform :ios, '9.0'
+platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
index 1a3f02c..0740c0e 100644
--- a/example/ios/Podfile.lock
+++ b/example/ios/Podfile.lock
@@ -2,21 +2,27 @@ PODS:
- Flutter (1.0.0)
- secure_application (0.0.1):
- Flutter
+ - url_launcher_ios (0.0.1):
+ - Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- secure_application (from `.symlinks/plugins/secure_application/ios`)
+ - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
secure_application:
:path: ".symlinks/plugins/secure_application/ios"
+ url_launcher_ios:
+ :path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
- Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
+ Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
secure_application: 27d424e8c2e770f63e38e280b5a51f921aa9b0c8
+ url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
-PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
+PODFILE CHECKSUM: 7368163408c647b7eb699d0d788ba6718e18fb8d
-COCOAPODS: 1.10.1
+COCOAPODS: 1.12.1
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index d605d68..6427efd 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 46;
+ objectVersion = 51;
objects = {
/* Begin PBXBuildFile section */
@@ -121,7 +121,6 @@
502301990184875FCF6A4E97 /* Pods-Runner.release.xcconfig */,
17B764A4A20FF79E31940E05 /* Pods-Runner.profile.xcconfig */,
);
- name = Pods;
path = Pods;
sourceTree = "";
};
@@ -358,7 +357,10 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
PRODUCT_BUNDLE_IDENTIFIER = org.jezequel.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -467,7 +469,8 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@@ -480,10 +483,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ DEVELOPMENT_TEAM = DZA2GZYF9B;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = org.jezequel.example;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = example.secure.application.kuama;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -501,7 +508,10 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
PRODUCT_BUNDLE_IDENTIFIER = org.jezequel.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 2c8ce77..d3e4fa6 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:secure_application/secure_application.dart';
+import 'package:url_launcher/url_launcher.dart';
void main() => runApp(MaterialApp(home: MyApp()));
@@ -88,6 +89,13 @@ class _MyAppState extends State {
child: Scaffold(
appBar: AppBar(
title: const Text('Secure Window Example'),
+ actions: [
+ IconButton(
+ onPressed: () =>
+ launchUrl(Uri.parse('https://example.com')),
+ icon: const Icon(Icons.share),
+ ),
+ ],
),
body: Center(
child: Builder(builder: (context) {
@@ -125,19 +133,19 @@ class _MyAppState extends State {
child: Text('Secure app'),
),
),
- if (failedAuth == null)
+ if (failedAuth)
Text(
'Lock the app then switch to another app and come back'),
- if (failedAuth != null)
- failedAuth
- ? Text(
- 'Auth failed we cleaned sensitive data',
- style: TextStyle(color: Colors.red),
- )
- : Text(
- 'Auth success',
- style: TextStyle(color: Colors.green),
- ),
+ if (failedAuth)
+ Text(
+ 'Auth failed we cleaned sensitive data',
+ style: TextStyle(color: Colors.red),
+ )
+ else
+ Text(
+ 'Auth success',
+ style: TextStyle(color: Colors.green),
+ ),
FlutterLogo(
size: width,
),
diff --git a/example/pubspec.lock b/example/pubspec.lock
index b5e1268..0fed498 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -5,58 +5,58 @@ packages:
dependency: transitive
description:
name: async
- url: "https://pub.dartlang.org"
+ sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+ url: "https://pub.dev"
source: hosted
- version: "2.8.2"
+ version: "2.10.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
- url: "https://pub.dartlang.org"
+ sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.0"
- charcode:
- dependency: transitive
- description:
- name: charcode
- url: "https://pub.dartlang.org"
+ sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+ url: "https://pub.dev"
source: hosted
- version: "1.3.1"
+ version: "1.2.1"
clock:
dependency: transitive
description:
name: clock
- url: "https://pub.dartlang.org"
+ sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
- url: "https://pub.dartlang.org"
+ sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+ url: "https://pub.dev"
source: hosted
- version: "1.15.0"
+ version: "1.17.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
- url: "https://pub.dartlang.org"
+ sha256: a937da4c006989739ceb4d10e3bd6cce64ca85d0fe287fc5b2b9f6ee757dcee6
+ url: "https://pub.dev"
source: hosted
version: "0.1.3"
fake_async:
dependency: transitive
description:
name: fake_async
- url: "https://pub.dartlang.org"
+ sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+ url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.3.1"
flutter:
dependency: "direct main"
description: flutter
@@ -66,7 +66,8 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
- url: "https://pub.dartlang.org"
+ sha256: "0ba8a1854c2098ddbd043e47eb28451a13f4cab7db9b2696f13a39fd8853421d"
+ url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_test:
@@ -83,37 +84,58 @@ packages:
dependency: transitive
description:
name: js
- url: "https://pub.dartlang.org"
+ sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+ url: "https://pub.dev"
source: hosted
- version: "0.6.3"
+ version: "0.6.5"
matcher:
dependency: transitive
description:
name: matcher
- url: "https://pub.dartlang.org"
+ sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.12.13"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
+ url: "https://pub.dev"
source: hosted
- version: "0.12.11"
+ version: "0.2.0"
meta:
dependency: transitive
description:
name: meta
- url: "https://pub.dartlang.org"
+ sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+ url: "https://pub.dev"
source: hosted
- version: "1.7.0"
+ version: "1.8.0"
path:
dependency: transitive
description:
name: path
- url: "https://pub.dartlang.org"
+ sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
+ url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.8.2"
+ plugin_platform_interface:
+ dependency: transitive
+ description:
+ name: plugin_platform_interface
+ sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.4"
rxdart:
dependency: transitive
description:
name: rxdart
- url: "https://pub.dartlang.org"
+ sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
+ url: "https://pub.dev"
source: hosted
- version: "0.26.0"
+ version: "0.27.7"
secure_application:
dependency: "direct dev"
description:
@@ -130,58 +152,122 @@ packages:
dependency: transitive
description:
name: source_span
- url: "https://pub.dartlang.org"
+ sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
+ url: "https://pub.dev"
source: hosted
- version: "1.8.1"
+ version: "1.9.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
- url: "https://pub.dartlang.org"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
+ url: "https://pub.dev"
source: hosted
- version: "1.10.0"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- url: "https://pub.dartlang.org"
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.0"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
- url: "https://pub.dartlang.org"
+ sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+ url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
- url: "https://pub.dartlang.org"
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
- url: "https://pub.dartlang.org"
+ sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
+ url: "https://pub.dev"
source: hosted
- version: "0.4.3"
- typed_data:
+ version: "0.4.16"
+ url_launcher:
+ dependency: "direct main"
+ description:
+ name: url_launcher
+ sha256: "75f2846facd11168d007529d6cd8fcb2b750186bea046af9711f10b907e1587e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.10"
+ url_launcher_android:
+ dependency: transitive
+ description:
+ name: url_launcher_android
+ sha256: "40612cd31902fe46b5158693faa65781b1ca7adfb883d77fa6f0d6dcf0317d85"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.0.30"
+ url_launcher_ios:
+ dependency: transitive
+ description:
+ name: url_launcher_ios
+ sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.4"
+ url_launcher_linux:
+ dependency: transitive
+ description:
+ name: url_launcher_linux
+ sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.5"
+ url_launcher_macos:
dependency: transitive
description:
- name: typed_data
- url: "https://pub.dartlang.org"
+ name: url_launcher_macos
+ sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e"
+ url: "https://pub.dev"
source: hosted
- version: "1.3.0"
+ version: "3.0.5"
+ url_launcher_platform_interface:
+ dependency: transitive
+ description:
+ name: url_launcher_platform_interface
+ sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.2"
+ url_launcher_web:
+ dependency: transitive
+ description:
+ name: url_launcher_web
+ sha256: "81fe91b6c4f84f222d186a9d23c73157dc4c8e1c71489c4d08be1ad3b228f1aa"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.16"
+ url_launcher_windows:
+ dependency: transitive
+ description:
+ name: url_launcher_windows
+ sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.6"
vector_math:
dependency: transitive
description:
name: vector_math
- url: "https://pub.dartlang.org"
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
source: hosted
- version: "2.1.1"
+ version: "2.1.4"
sdks:
- dart: ">=2.14.0 <3.0.0"
- flutter: ">=1.20.0"
+ dart: ">=2.18.0 <3.0.0"
+ flutter: ">=3.3.0"
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index cccb0c3..d4d5dda 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -13,6 +13,8 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
+ url_launcher: ^6.1.10
+
dev_dependencies:
flutter_test:
sdk: flutter
diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart
deleted file mode 100644
index 68a06fa..0000000
--- a/example/test/widget_test.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// This is a basic Flutter widget test.
-//
-// To perform an interaction with a widget in your test, use the WidgetTester
-// utility that Flutter provides. For example, you can send tap and scroll
-// gestures. You can also use WidgetTester to find child widgets in the widget
-// tree, read text, and verify that the values of widget properties are correct.
-
-import 'package:flutter/material.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'package:secure_application_example/main.dart';
-
-void main() {}
diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc
index b359ee1..d0dcaa2 100644
--- a/example/windows/flutter/generated_plugin_registrant.cc
+++ b/example/windows/flutter/generated_plugin_registrant.cc
@@ -2,11 +2,16 @@
// Generated file. Do not edit.
//
+// clang-format off
+
#include "generated_plugin_registrant.h"
#include
+#include
void RegisterPlugins(flutter::PluginRegistry* registry) {
SecureApplicationPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SecureApplicationPlugin"));
+ UrlLauncherWindowsRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}
diff --git a/example/windows/flutter/generated_plugin_registrant.h b/example/windows/flutter/generated_plugin_registrant.h
index 9846246..dc139d8 100644
--- a/example/windows/flutter/generated_plugin_registrant.h
+++ b/example/windows/flutter/generated_plugin_registrant.h
@@ -2,6 +2,8 @@
// Generated file. Do not edit.
//
+// clang-format off
+
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
diff --git a/example/windows/flutter/generated_plugins.cmake b/example/windows/flutter/generated_plugins.cmake
index 6a5fe7f..8dd4cd0 100644
--- a/example/windows/flutter/generated_plugins.cmake
+++ b/example/windows/flutter/generated_plugins.cmake
@@ -4,6 +4,10 @@
list(APPEND FLUTTER_PLUGIN_LIST
secure_application
+ url_launcher_windows
+)
+
+list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES)
@@ -14,3 +18,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)
+
+foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
+ add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
+ list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
+endforeach(ffi_plugin)
diff --git a/ios/Classes/SwiftSecureApplicationPlugin.swift b/ios/Classes/SwiftSecureApplicationPlugin.swift
index 2fab50e..c4435cc 100644
--- a/ios/Classes/SwiftSecureApplicationPlugin.swift
+++ b/ios/Classes/SwiftSecureApplicationPlugin.swift
@@ -3,10 +3,9 @@ import UIKit
public class SwiftSecureApplicationPlugin: NSObject, FlutterPlugin {
var secured = false;
+ var secureView = UIVisualEffectView()
var opacity: CGFloat = 0.2;
- var backgroundTask: UIBackgroundTaskIdentifier!
-
internal let registrar: FlutterPluginRegistrar
init(registrar: FlutterPluginRegistrar) {
@@ -20,82 +19,63 @@ public class SwiftSecureApplicationPlugin: NSObject, FlutterPlugin {
let instance = SwiftSecureApplicationPlugin(registrar: registrar)
registrar.addMethodCallDelegate(instance, channel: channel)
}
-
- public func applicationWillResignActive(_ application: UIApplication) {
- if ( secured ) {
- self.registerBackgroundTask()
- UIApplication.shared.ignoreSnapshotOnNextApplicationLaunch()
- if let window = UIApplication.shared.windows.filter({ (w) -> Bool in
- return w.isHidden == false
- }).first {
- if let existingView = window.viewWithTag(99699), let existingBlurrView = window.viewWithTag(99698) {
- window.bringSubviewToFront(existingView)
- window.bringSubviewToFront(existingBlurrView)
- return
- } else {
- let colorView = UIView(frame: window.bounds);
- colorView.tag = 99699
- colorView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
- colorView.backgroundColor = UIColor(white: 1, alpha: opacity)
- window.addSubview(colorView)
- window.bringSubviewToFront(colorView)
-
- let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.extraLight)
- let blurEffectView = UIVisualEffectView(effect: blurEffect)
- blurEffectView.frame = window.bounds
- blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
-
- blurEffectView.tag = 99698
-
- window.addSubview(blurEffectView)
- window.bringSubviewToFront(blurEffectView)
- window.snapshotView(afterScreenUpdates: true)
- RunLoop.current.run(until: Date(timeIntervalSinceNow:0.5))
- }
- }
- self.endBackgroundTask()
- }
- }
- func registerBackgroundTask() {
- self.backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
- self?.endBackgroundTask()
- }
- assert(self.backgroundTask != UIBackgroundTaskIdentifier.invalid)
+
+ public func applicationWillEnterForeground(_ application: UIApplication) {
+ self.unlockApp()
}
- func endBackgroundTask() {
- print("Background task ended.")
- UIApplication.shared.endBackgroundTask(backgroundTask)
- backgroundTask = UIBackgroundTaskIdentifier.invalid
+ public func applicationWillResignActive(_ application: UIApplication) {
+ if !secured { return }
+ self.lockApp()
}
-
+
+ public func applicationDidBecomeActive(_ application: UIApplication) {
+ self.unlockApp()
+ }
+
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
- if (call.method == "secure") {
+ switch (call.method) {
+ case "secure":
secured = true;
+ result(nil)
+ case "open":
+ secured = false;
+ self.unlockApp()
+ result(nil)
+ case "opacity":
if let args = call.arguments as? Dictionary,
- let opacity = args["opacity"] as? NSNumber {
+ let opacity = args["opacity"] as? NSNumber {
self.opacity = opacity as! CGFloat
}
- } else if (call.method == "open") {
- secured = false;
- } else if (call.method == "opacity") {
- if let args = call.arguments as? Dictionary,
- let opacity = args["opacity"] as? NSNumber {
- self.opacity = opacity as! CGFloat
- }
- } else if (call.method == "unlock") {
- if let window = UIApplication.shared.windows.filter({ (w) -> Bool in
- return w.isHidden == false
- }).first, let view = window.viewWithTag(99699), let blurrView = window.viewWithTag(99698) {
- UIView.animate(withDuration: 0.5, animations: {
- view.alpha = 0.0
- blurrView.alpha = 0.0
- }, completion: { finished in
- view.removeFromSuperview()
- blurrView.removeFromSuperview()
-
- })
- }
+ result(nil)
+ default:
+ result(FlutterMethodNotImplemented)
}
}
+
+ private func unlockApp() {
+ UIView.animate(withDuration: 0.3, animations: { [weak self] in
+ guard let self else { return }
+ self.secureView.backgroundColor = UIColor(white: 1, alpha: 0.0)
+ self.secureView.effect = nil
+ }, completion: { [weak self] (_) in
+ guard let self else { return }
+ self.secureView.removeFromSuperview()
+ })
+ }
+
+ private func lockApp() {
+ let window = UIApplication.shared.windows.first
+
+ if let window, !self.secureView.isDescendant(of: window) {
+ self.secureView.frame = window.bounds
+ UIView.animate(withDuration: 0.3) { [weak self] in
+ guard let self else { return }
+ self.secureView.backgroundColor = UIColor(white: 1, alpha: self.opacity)
+ self.secureView.effect = UIBlurEffect(style: .light)
+ }
+ window.addSubview(self.secureView)
+ window.snapshotView(afterScreenUpdates: true)
+ }
+ }
}
diff --git a/lib/secure_application.dart b/lib/secure_application.dart
index 70acb6d..446ff62 100644
--- a/lib/secure_application.dart
+++ b/lib/secure_application.dart
@@ -1,16 +1,16 @@
import 'dart:async';
import 'package:flutter/widgets.dart';
+import 'package:secure_application/secure_application_controller.dart';
import 'package:secure_application/secure_application_native.dart';
import 'package:secure_application/secure_application_provider.dart';
import 'package:secure_application/secure_application_state.dart';
-import 'package:secure_application/secure_application_controller.dart';
export './secure_application.dart';
-export './secure_gate.dart';
+export './secure_application_controller.dart';
export './secure_application_provider.dart';
export './secure_application_state.dart';
-export './secure_application_controller.dart';
+export './secure_gate.dart';
/// Widget that will manage Secure Gates and visibility protection for your app content
///
@@ -22,6 +22,8 @@ class SecureApplication extends StatefulWidget {
/// This will remove IOs glass effect from native automatically. To set to true (default) if you don't want to manage it
/// you can play with the [nativeRemoveDelay] to avoid iOS unsecure flicker
+ @Deprecated(
+ 'It is handled internally on ios getting the same behavior as on android. This flag will no longer have any effect')
final bool autoUnlockNative;
/// Method will be called when the user switch back to your application
@@ -83,7 +85,6 @@ class _SecureApplicationState extends State
return _secureApplicationController!;
}
- bool _removeNativeOnNextFrame = false;
@override
void initState() {
_authStreamSubscription =
@@ -116,17 +117,12 @@ class _SecureApplicationState extends State
void didChangeAppLifecycleState(AppLifecycleState state) async {
switch (state) {
case AppLifecycleState.resumed:
- if (mounted) {
- setState(() => _removeNativeOnNextFrame = true);
- } else {
- _removeNativeOnNextFrame = true;
- }
if (!secureApplicationController.paused) {
if (secureApplicationController.secured &&
secureApplicationController.value.locked) {
if (widget.onNeedUnlock != null) {
secureApplicationController.pause();
- var authStatus =
+ final authStatus =
await widget.onNeedUnlock!(secureApplicationController);
if (authStatus != null)
secureApplicationController.sendAuthenticationEvent(authStatus);
@@ -138,7 +134,6 @@ class _SecureApplicationState extends State
}
secureApplicationController.resumed();
}
- super.didChangeAppLifecycleState(state);
break;
case AppLifecycleState.paused:
if (!secureApplicationController.paused) {
@@ -146,22 +141,15 @@ class _SecureApplicationState extends State
secureApplicationController.lock();
}
}
- super.didChangeAppLifecycleState(state);
break;
default:
- super.didChangeAppLifecycleState(state);
break;
}
+ super.didChangeAppLifecycleState(state);
}
@override
Widget build(BuildContext context) {
- if (_removeNativeOnNextFrame && widget.autoUnlockNative) {
- Future.delayed(Duration(milliseconds: widget.nativeRemoveDelay))
- .then((_) => SecureApplicationNative.unlock());
-
- _removeNativeOnNextFrame = false;
- }
return SecureApplicationProvider(
secureData: secureApplicationController,
child: widget.child,
diff --git a/lib/secure_application_controller.dart b/lib/secure_application_controller.dart
index 648ece8..f5baaa0 100644
--- a/lib/secure_application_controller.dart
+++ b/lib/secure_application_controller.dart
@@ -94,7 +94,6 @@ class SecureApplicationController
/// content under [SecureGate] will not be visible
void lock() {
- SecureApplicationNative.lock();
if (!value.locked) {
value = value.copyWith(locked: true);
notifyListeners();
@@ -108,8 +107,6 @@ class SecureApplicationController
/// Use when you want your user to see content under [SecureGate]
void unlock() {
- SecureApplicationNative
- .unlock(); //lock from native is removed when resumed but why not!
if (value.locked) {
value = value.copyWith(locked: false);
notifyListeners();
@@ -119,7 +116,6 @@ class SecureApplicationController
/// temporary prevent the app from locking if use leave and come back to the app
void pause() {
- SecureApplicationNative.lock();
if (!value.paused) {
value = value.copyWith(paused: true);
notifyListeners();
@@ -142,7 +138,7 @@ class SecureApplicationController
/// App will be secured and content will not be visible if user switch app
///
- /// on Android this will also prevent scrensshot/screen recording
+ /// on Android this will also prevent screenshot/screen recording
void secure() {
SecureApplicationNative.secure();
if (!value.secured) {
diff --git a/lib/secure_application_native.dart b/lib/secure_application_native.dart
index 6f710c0..2448f67 100644
--- a/lib/secure_application_native.dart
+++ b/lib/secure_application_native.dart
@@ -1,19 +1,22 @@
import 'dart:async';
-import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
class SecureApplicationNative {
static const MethodChannel _channel =
const MethodChannel('secure_application');
+ /// Implemented only in windows
static void registerForEvents(VoidCallback lock, VoidCallback unlock) {
_channel.setMethodCallHandler(
(call) => secureApplicationHandler(call, lock, unlock));
}
- static Future secureApplicationHandler(
- MethodCall methodCall, lock, unlock) async {
+ static Future secureApplicationHandler(
+ MethodCall methodCall,
+ VoidCallback lock,
+ VoidCallback unlock,
+ ) async {
switch (methodCall.method) {
case 'lock':
lock();
@@ -26,23 +29,28 @@ class SecureApplicationNative {
}
}
- static Future secure() {
+ /// App will be secured and content will not be visible if user switch app
+ ///
+ /// on Android this will also prevent screenshot/screen recording
+ static Future secure() {
return _channel.invokeMethod('secure');
}
- static Future open() {
+ /// App will no longer be secured and content will be visible if user switch app
+ static Future open() {
return _channel.invokeMethod('open');
}
- static Future lock() {
- return _channel.invokeMethod('lock');
- }
+ /// Temporary prevent the app from locking if use leave and come back to the app
+ @Deprecated('It never did anything')
+ static Future lock() async {}
- static Future unlock() {
- return _channel.invokeMethod('unlock');
- }
+ /// Use when you want your user to see content
+ @Deprecated('It never did anything')
+ static Future unlock() async {}
- static Future opacity(double opacity) {
- return _channel.invokeMethod('opacity', {"opacity": opacity});
+ /// Only work on ios
+ static Future opacity(double opacity) {
+ return _channel.invokeMethod('opacity', {'opacity': opacity});
}
}
diff --git a/lib/secure_application_state.dart b/lib/secure_application_state.dart
index ee66078..6987504 100644
--- a/lib/secure_application_state.dart
+++ b/lib/secure_application_state.dart
@@ -7,6 +7,7 @@ class SecureApplicationState {
final bool secured;
final bool paused;
final bool authenticated;
+
SecureApplicationState({
this.locked = false,
this.secured = false,
diff --git a/pubspec.lock b/pubspec.lock
deleted file mode 100644
index 0de7638..0000000
--- a/pubspec.lock
+++ /dev/null
@@ -1,173 +0,0 @@
-# Generated by pub
-# See https://dart.dev/tools/pub/glossary#lockfile
-packages:
- async:
- dependency: transitive
- description:
- name: async
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.8.2"
- boolean_selector:
- dependency: transitive
- description:
- name: boolean_selector
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.0"
- characters:
- dependency: transitive
- description:
- name: characters
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.0"
- charcode:
- dependency: transitive
- description:
- name: charcode
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.3.1"
- clock:
- dependency: transitive
- description:
- name: clock
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.0"
- collection:
- dependency: transitive
- description:
- name: collection
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.15.0"
- fake_async:
- dependency: transitive
- description:
- name: fake_async
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.0"
- flutter:
- dependency: "direct main"
- description: flutter
- source: sdk
- version: "0.0.0"
- flutter_plugin_android_lifecycle:
- dependency: "direct main"
- description:
- name: flutter_plugin_android_lifecycle
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.2"
- flutter_test:
- dependency: "direct dev"
- description: flutter
- source: sdk
- version: "0.0.0"
- flutter_web_plugins:
- dependency: "direct main"
- description: flutter
- source: sdk
- version: "0.0.0"
- js:
- dependency: transitive
- description:
- name: js
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.6.3"
- matcher:
- dependency: transitive
- description:
- name: matcher
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.12.11"
- meta:
- dependency: transitive
- description:
- name: meta
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.7.0"
- path:
- dependency: transitive
- description:
- name: path
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.8.0"
- rxdart:
- dependency: "direct main"
- description:
- name: rxdart
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.26.0"
- sky_engine:
- dependency: transitive
- description: flutter
- source: sdk
- version: "0.0.99"
- source_span:
- dependency: transitive
- description:
- name: source_span
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.8.1"
- stack_trace:
- dependency: transitive
- description:
- name: stack_trace
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.10.0"
- stream_channel:
- dependency: transitive
- description:
- name: stream_channel
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.0"
- string_scanner:
- dependency: transitive
- description:
- name: string_scanner
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.0"
- term_glyph:
- dependency: transitive
- description:
- name: term_glyph
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.0"
- test_api:
- dependency: transitive
- description:
- name: test_api
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.4.3"
- typed_data:
- dependency: transitive
- description:
- name: typed_data
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.3.0"
- vector_math:
- dependency: transitive
- description:
- name: vector_math
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.1"
-sdks:
- dart: ">=2.14.0 <3.0.0"
- flutter: ">=1.20.0"