diff --git a/.circleci/config.yml b/.circleci/config.yml index 2cc6ada92..0d5343223 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -237,7 +237,7 @@ jobs: - setup_flutter - android/start-emulator-and-run-tests: run-tests-working-directory: e2e - additional-avd-args: --device 3 + additional-avd-args: --device 25 system-image: system-images;android-33;default;x86_64 post-emulator-launch-assemble-command: cd packages/instabug_flutter/example && flutter build apk --debug test-command: dotnet test @@ -278,7 +278,7 @@ jobs: command: flutter build ios --simulator - run: name: Run E2E Tests - no_output_timeout: 30m + no_output_timeout: 20m working_directory: e2e command: dotnet test diff --git a/e2e/BugReportingTests.cs b/e2e/BugReportingTests.cs index f938cfcbd..f48afbf3b 100644 --- a/e2e/BugReportingTests.cs +++ b/e2e/BugReportingTests.cs @@ -1,9 +1,9 @@ -using System.Drawing; using E2E.Utils; using Xunit; using Instabug.Captain; using NoSuchElementException = OpenQA.Selenium.NoSuchElementException; +using System.Drawing; namespace E2E; @@ -46,6 +46,9 @@ public void ReportABug() [Fact] public void FloatingButtonInvocationEvent() { + + Console.WriteLine("FloatingButtonInvocationEvent"); + captain.FindById( android: "instabug_floating_button", ios: "IBGFloatingButtonAccessibilityIdentifier" @@ -57,9 +60,13 @@ public void FloatingButtonInvocationEvent() [Fact] public void ShakeInvocationEvent() { + + Console.WriteLine("ShakeInvocationEvent"); + if (!Platform.IsIOS) return; - captain.FindByText("Shake").Tap(); + + captain.FindByTextScroll("Shake").Tap(); captain.Shake(); @@ -69,8 +76,12 @@ public void ShakeInvocationEvent() [Fact] public void TwoFingersSwipeLeftInvocationEvent() { - ScrollUp(); - captain.FindByText("Two Fingers Swipe Left").Tap(); + + Console.WriteLine("TwoFingersSwipeLeftInvocationEvent"); + + + + captain.FindByTextScroll("Two Fingers Swipe Left").Tap(); Thread.Sleep(500); @@ -89,7 +100,11 @@ public void TwoFingersSwipeLeftInvocationEvent() [Fact] public void NoneInvocationEvent() { - captain.FindByText("None").Tap(); + + Console.WriteLine("NoneInvocationEvent"); + + + captain.FindByTextScroll("None").Tap(); captain.WaitForAssertion(() => Assert.Throws(() => @@ -105,7 +120,13 @@ public void NoneInvocationEvent() [Fact] public void ManualInvocation() { - captain.FindByText("Invoke").Tap(); + + + Console.WriteLine("ManualInvocation"); + + + + captain.FindByTextScroll("Invoke").Tap(); AssertOptionsPromptIsDisplayed(); } @@ -113,14 +134,24 @@ public void ManualInvocation() [Fact] public void MultipleScreenshotsInReproSteps() { - ScrollDownLittle(); - captain.FindByText("Enter screen name").Tap(); + + Console.WriteLine("MultipleScreenshotsInReproSteps"); + + + + +captain.FindByTextScroll("Enter screen name").Tap(); captain.Type("My Screen"); captain.HideKeyboard(); - captain.FindByText("Report Screen Change").Tap(); - captain.FindByText("Send Bug Report").Tap(); + captain.HideKeyboard(); + Thread.Sleep(500); + + captain.FindByTextScroll("Report Screen Change")?.Tap(); + Thread.Sleep(500); + captain.FindByTextScroll("Send Bug Report")?.Tap(); + captain.FindById( android: "instabug_text_view_repro_steps_disclaimer", ios: "IBGBugVCReproStepsDisclaimerAccessibilityIdentifier" @@ -136,27 +167,30 @@ public void MultipleScreenshotsInReproSteps() [Fact(Skip = "The test is flaky on iOS so we're skipping it to unblock the v13.2.0 release")] public void ChangeReportTypes() { - ScrollUp(); - captain.FindByText("Bug", exact: true).Tap(); + + Console.WriteLine("ChangeReportTypes"); + + + captain.FindByTextScroll("Bug", exact: true).Tap(); if (Platform.IsAndroid) { - captain.FindByText("Invoke").Tap(); + captain.FindByTextScroll("Invoke").Tap(); // Shows bug reporting screen Assert.True(captain.FindById("ib_bug_scroll_view").Displayed); // Close bug reporting screen captain.GoBack(); - captain.FindByText("DISCARD").Tap(); + captain.FindByTextScroll("DISCARD").Tap(); Thread.Sleep(500); } - captain.FindByText("Feedback").Tap(); + captain.FindByTextScroll("Feedback").Tap(); - captain.FindByText("Invoke").Tap(); + captain.FindByTextScroll("Invoke").Tap(); // Shows both bug reporting and feature requests in prompt options AssertOptionsPromptIsDisplayed(); @@ -169,10 +203,12 @@ public void ChangeReportTypes() [Fact] public void ChangeFloatingButtonEdge() { - ScrollDown(); - captain.FindByText("Move Floating Button to Left").Tap(); - Thread.Sleep(500); + Console.WriteLine("ChangeFloatingButtonEdge"); + + + captain.FindByTextScroll("Move Floating Button to Left",false,false)?.Tap(); + captain.WaitForAssertion(() => { @@ -189,16 +225,16 @@ public void ChangeFloatingButtonEdge() [Fact] public void OnDismissCallbackIsCalled() { - ScrollDownLittle(); - captain.FindByText("Set On Dismiss Callback").Tap(); - captain.FindByText("Invoke").Tap(); + captain.FindByTextScroll("Set On Dismiss Callback",false,false).Tap(); + captain.FindByTextScroll("Invoke",false,false).Tap(); AssertOptionsPromptIsDisplayed(); - captain.FindByText("Cancel").Tap(); + captain.FindByTextScroll("Cancel").Tap(); var popUpText = captain.FindByText("onDismiss callback called with DismissType.cancel and ReportType.other"); Assert.True(popUpText.Displayed); + } } diff --git a/e2e/FeatureRequestsTests.cs b/e2e/FeatureRequestsTests.cs index 41c97f684..724758bee 100644 --- a/e2e/FeatureRequestsTests.cs +++ b/e2e/FeatureRequestsTests.cs @@ -10,10 +10,10 @@ public class FeatureRequestsTests : CaptainTest [Fact] public void ShowFeatureRequetsScreen() { - ScrollDown(); - ScrollDown(); - captain.FindByText("Show Feature Requests").Tap(); + Console.WriteLine("ShowFeatureRequetsScreen"); + + captain.FindByTextScroll("Show Feature Requests",false,false).Tap(); var screenTitle = captain.FindById( android: "ib_fr_toolbar_main", diff --git a/e2e/InstabugTests.cs b/e2e/InstabugTests.cs index 1b67ae8cd..e376f87bf 100644 --- a/e2e/InstabugTests.cs +++ b/e2e/InstabugTests.cs @@ -11,14 +11,16 @@ public class InstabugTests : CaptainTest [Fact] public void ChangePrimaryColor() { + Console.WriteLine("ChangePrimaryColor"); + var color = "#FF0000"; var expected = Color.FromArgb(255, 0, 0); - captain.FindByText("Enter primary color").Tap(); + captain.FindByTextScroll("Enter primary color").Tap(); captain.Type(color); captain.HideKeyboard(); - captain.FindByText("Change Primary Color").Tap(); + captain.FindByTextScroll("Change Primary Color").Tap(); captain.WaitForAssertion(() => { diff --git a/e2e/SurveysTests.cs b/e2e/SurveysTests.cs index 1ed0eba48..0d67f99ab 100644 --- a/e2e/SurveysTests.cs +++ b/e2e/SurveysTests.cs @@ -10,8 +10,9 @@ public class SurveysTests : CaptainTest [Fact] public void ShowManualSurvey() { - ScrollDownLittle(); - captain.FindByText("Show Manual Survey").Tap(); + Console.WriteLine("ShowManualSurvey"); + + captain.FindByTextScroll("Show Manual Survey",false,false).Tap(); captain.WaitForAssertion(() => { diff --git a/e2e/Utils/CaptainTest.cs b/e2e/Utils/CaptainTest.cs index 3b42f13cb..e32255d4b 100644 --- a/e2e/Utils/CaptainTest.cs +++ b/e2e/Utils/CaptainTest.cs @@ -1,5 +1,7 @@ using System.Drawing; using Instabug.Captain; +using OpenQA.Selenium; +using OpenQA.Selenium.Appium.MultiTouch; namespace E2E.Utils; @@ -10,6 +12,7 @@ public class CaptainTest : IDisposable AndroidApp = Path.GetFullPath("../../../../packages/instabug_flutter/example/build/app/outputs/flutter-apk/app-debug.apk"), AndroidAppId = "com.instabug.flutter.example", AndroidVersion = "13", + IosApp = Path.GetFullPath("../../../../packages/instabug_flutter/example/build/ios/iphonesimulator/Runner.app"), IosAppId = "com.instabug.InstabugSample", IosVersion = "17.2", @@ -28,28 +31,5 @@ public void Dispose() captain.RestartApp(); } - protected void ScrollDown() - { - captain.Swipe( - start: new Point(captain.Window.Size.Width / 2, captain.Window.Size.Height - 200), - end: new Point(captain.Window.Size.Width / 2, 250) - ); - } - - protected void ScrollDownLittle() - { - captain.Swipe( - start: new Point(captain.Window.Size.Width / 2, captain.Window.Size.Height - 200), - end: new Point(captain.Window.Size.Width / 2, captain.Window.Size.Height - 220) - ); - } - - protected void ScrollUp() - { - captain.Swipe( - start: new Point(captain.Window.Size.Width / 2, 250), - end: new Point(captain.Window.Size.Width / 2, captain.Window.Size.Height - 200) - ); - } } diff --git a/packages/instabug_dio_interceptor/example/pubspec.lock b/packages/instabug_dio_interceptor/example/pubspec.lock index cc912e03a..c05b421e4 100644 --- a/packages/instabug_dio_interceptor/example/pubspec.lock +++ b/packages/instabug_dio_interceptor/example/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" cupertino_icons: dependency: "direct main" description: @@ -117,18 +117,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -181,7 +181,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -194,10 +194,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -210,10 +210,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" term_glyph: dependency: transitive description: @@ -226,10 +226,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" typed_data: dependency: transitive description: @@ -250,10 +250,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" web: dependency: transitive description: diff --git a/packages/instabug_dio_interceptor/lib/instabug_dio_interceptor.dart b/packages/instabug_dio_interceptor/lib/instabug_dio_interceptor.dart index 72b8af3ae..36d2c9e01 100644 --- a/packages/instabug_dio_interceptor/lib/instabug_dio_interceptor.dart +++ b/packages/instabug_dio_interceptor/lib/instabug_dio_interceptor.dart @@ -85,6 +85,7 @@ class InstabugDioInterceptor extends Interceptor { if (responseHeaders.containsKey('content-length')) { // ignore: avoid_dynamic_calls responseBodySize = + // ignore: avoid_dynamic_calls int.parse((responseHeaders['content-length'][0]) ?? '0'); } else if (response.data != null) { responseBodySize = response.data.toString().length; diff --git a/packages/instabug_dio_interceptor/pubspec.lock b/packages/instabug_dio_interceptor/pubspec.lock index 753b9a7fe..8a2504759 100644 --- a/packages/instabug_dio_interceptor/pubspec.lock +++ b/packages/instabug_dio_interceptor/pubspec.lock @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" convert: dependency: transitive description: @@ -326,18 +326,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -518,7 +518,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_gen: dependency: transitive description: @@ -555,10 +555,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -579,10 +579,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" tar: dependency: transitive description: @@ -603,26 +603,26 @@ packages: dependency: transitive description: name: test - sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" + sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f" url: "https://pub.dev" source: hosted - version: "1.25.7" + version: "1.25.8" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" test_core: dependency: transitive description: name: test_core - sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" + sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d" url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" timing: dependency: transitive description: @@ -651,10 +651,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" watcher: dependency: transitive description: diff --git a/packages/instabug_flutter/android/build.gradle b/packages/instabug_flutter/android/build.gradle index e3b5d0bca..fc96676b8 100644 --- a/packages/instabug_flutter/android/build.gradle +++ b/packages/instabug_flutter/android/build.gradle @@ -1,5 +1,5 @@ group 'com.instabug.flutter' -version '14.1.0' +version '15.0.1' buildscript { repositories { @@ -16,6 +16,13 @@ rootProject.allprojects { repositories { google() mavenCentral() + maven { + url "https://mvn.instabug.com/nexus/repository/instabug-internal/" + credentials { + username "instabug" + password System.getenv('INSTABUG_REPOSITORY_PASSWORD') + } + } } } @@ -44,11 +51,12 @@ android { } dependencies { - api 'com.instabug.library:instabug:14.1.0' + api 'com.instabug.library:instabug:14.2.0.6611870-SNAPSHOT' + testImplementation 'junit:junit:4.13.2' testImplementation "org.mockito:mockito-inline:3.12.1" testImplementation "io.mockk:mockk:1.13.13" - + testImplementation "org.robolectric:robolectric:4.12.2" } // add upload_symbols task diff --git a/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/InstabugFlutterPlugin.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/InstabugFlutterPlugin.java index b79d82dbb..39089fffe 100644 --- a/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/InstabugFlutterPlugin.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/InstabugFlutterPlugin.java @@ -10,16 +10,20 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.instabug.flutter.generated.InstabugPrivateViewPigeon; import com.instabug.flutter.modules.ApmApi; import com.instabug.flutter.modules.BugReportingApi; import com.instabug.flutter.modules.CrashReportingApi; import com.instabug.flutter.modules.FeatureRequestsApi; import com.instabug.flutter.modules.InstabugApi; import com.instabug.flutter.modules.InstabugLogApi; +import com.instabug.flutter.modules.InstabugPrivateView; +import com.instabug.flutter.modules.PrivateViewManager; import com.instabug.flutter.modules.RepliesApi; import com.instabug.flutter.modules.SessionReplayApi; import com.instabug.flutter.modules.SurveysApi; -import com.instabug.library.internal.crossplatform.InternalCore; +import com.instabug.flutter.modules.capturing.BoundryCaptureManager; +import com.instabug.flutter.modules.capturing.PixelCopyCaptureManager; import java.util.concurrent.Callable; @@ -28,7 +32,6 @@ import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.embedding.engine.renderer.FlutterRenderer; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.PluginRegistry.Registrar; public class InstabugFlutterPlugin implements FlutterPlugin, ActivityAware { private static final String TAG = InstabugFlutterPlugin.class.getName(); @@ -37,14 +40,9 @@ public class InstabugFlutterPlugin implements FlutterPlugin, ActivityAware { private static Activity activity; - /** - * Embedding v1 - */ - @SuppressWarnings("deprecation") - public static void registerWith(Registrar registrar) { - activity = registrar.activity(); - register(registrar.context().getApplicationContext(), registrar.messenger(), (FlutterRenderer) registrar.textures()); - } + private static PrivateViewManager privateViewManager; + + @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { @@ -59,21 +57,31 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { @Override public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { activity = binding.getActivity(); + if (privateViewManager != null) { + privateViewManager.setActivity(activity); + } } @Override public void onDetachedFromActivityForConfigChanges() { activity = null; + privateViewManager.setActivity(null); + } @Override public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { activity = binding.getActivity(); + if (privateViewManager != null) { + privateViewManager.setActivity(activity); + } } @Override public void onDetachedFromActivity() { activity = null; + privateViewManager.setActivity(null); + } private static void register(Context context, BinaryMessenger messenger, FlutterRenderer renderer) { @@ -84,6 +92,9 @@ public Bitmap call() { } }; + privateViewManager = new PrivateViewManager(new InstabugPrivateViewPigeon.InstabugPrivateViewFlutterApi(messenger), new PixelCopyCaptureManager(), new BoundryCaptureManager(renderer)); + InstabugPrivateView.init(messenger, privateViewManager); + ApmApi.init(messenger); BugReportingApi.init(messenger); CrashReportingApi.init(messenger); @@ -93,6 +104,7 @@ public Bitmap call() { RepliesApi.init(messenger); SessionReplayApi.init(messenger); SurveysApi.init(messenger); + } @Nullable diff --git a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/model/ScreenshotResult.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/model/ScreenshotResult.java similarity index 89% rename from packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/model/ScreenshotResult.java rename to packages/instabug_flutter/android/src/main/java/com/instabug/flutter/model/ScreenshotResult.java index 107d431d2..66a3c51cb 100644 --- a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/model/ScreenshotResult.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/model/ScreenshotResult.java @@ -1,4 +1,4 @@ -package com.instabug.instabug_private_views.model; +package com.instabug.flutter.model; import android.graphics.Bitmap; diff --git a/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/InstabugApi.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/InstabugApi.java index 45ee1d9cc..1e1617df0 100644 --- a/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/InstabugApi.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/InstabugApi.java @@ -6,13 +6,16 @@ import android.graphics.BitmapFactory; import android.net.Uri; import android.util.Log; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; + import com.instabug.flutter.generated.InstabugPigeon; import com.instabug.flutter.util.ArgsRegistry; import com.instabug.flutter.util.Reflection; import com.instabug.flutter.util.ThreadManager; +import com.instabug.library.MaskingType; import com.instabug.library.ReproMode; import com.instabug.library.internal.crossplatform.CoreFeature; import com.instabug.library.internal.crossplatform.CoreFeaturesState; @@ -33,9 +36,11 @@ import com.instabug.library.model.NetworkLog; import com.instabug.library.screenshot.instacapture.ScreenshotRequest; import com.instabug.library.ui.onboarding.WelcomeMessage; + import io.flutter.FlutterInjector; import io.flutter.embedding.engine.loader.FlutterLoader; import io.flutter.plugin.common.BinaryMessenger; + import org.jetbrains.annotations.NotNull; import org.json.JSONObject; @@ -44,6 +49,8 @@ import java.io.InputStream; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -105,7 +112,9 @@ public Boolean isEnabled() { @NotNull @Override - public Boolean isBuilt() { return Instabug.isBuilt(); } + public Boolean isBuilt() { + return Instabug.isBuilt(); + } @Override public void init(@NonNull String token, @NonNull List invocationEvents, @NonNull String debugLogsLevel) { @@ -126,6 +135,27 @@ public void init(@NonNull String token, @NonNull List invocationEvents, .build(); Instabug.setScreenshotProvider(screenshotProvider); + + try { + Class myClass = Class.forName("com.instabug.library.Instabug"); + // Enable/Disable native user steps capturing + Method method = myClass.getDeclaredMethod("shouldDisableNativeUserStepsCapturing", boolean.class); + method.setAccessible(true); + method.invoke(null, true); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void enableAutoMasking(@NonNull List autoMasking) { + int[] autoMaskingArray = new int[autoMasking.size()]; + for (int i = 0; i < autoMasking.size(); i++) { + String key = autoMasking.get(i); + autoMaskingArray[i] = ArgsRegistry.autoMasking.get(key); + } + + Instabug.setAutoMaskScreenshotsTypes(Arrays.copyOf(autoMaskingArray, autoMaskingArray.length)); } @Override @@ -159,6 +189,33 @@ public void logOut() { Instabug.logoutUser(); } + @Override + public void setEnableUserSteps(@NonNull Boolean isEnabled) { + Instabug.setTrackingUserStepsState(isEnabled ? Feature.State.ENABLED : Feature.State.DISABLED); + } + + @Override + + public void logUserSteps(@NonNull String gestureType, @NonNull String message, @Nullable String viewName) { + try { + final String stepType = ArgsRegistry.gestureStepType.get(gestureType); + final long timeStamp = System.currentTimeMillis(); + String view = ""; + + Method method = Reflection.getMethod(Class.forName("com.instabug.library.Instabug"), "addUserStep", + long.class, String.class, String.class, String.class, String.class); + if (method != null) { + if (viewName != null) { + view = viewName; + } + + method.invoke(null, timeStamp, stepType, message, null, view); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + @Override public void setLocale(@NonNull String locale) { final InstabugLocale resolvedLocale = ArgsRegistry.locales.get(locale); @@ -362,6 +419,13 @@ public void reportScreenChange(@NonNull String screenName) { if (method != null) { method.invoke(null, null, screenName); } + + Method reportViewChange = Reflection.getMethod(Class.forName("com.instabug.library.Instabug"), "reportCurrentViewChange", + String.class); + if (reportViewChange != null) { + reportViewChange.invoke(null, screenName); + } + } catch (Exception e) { e.printStackTrace(); } @@ -497,7 +561,7 @@ public void willRedirectToStore() { Instabug.willRedirectToStore(); } - public static void setScreenshotCaptor(ScreenshotCaptor screenshotCaptor,InternalCore internalCore) { + public static void setScreenshotCaptor(ScreenshotCaptor screenshotCaptor, InternalCore internalCore) { internalCore._setScreenshotCaptor(new com.instabug.library.screenshot.ScreenshotCaptor() { @Override public void capture(@NonNull ScreenshotRequest screenshotRequest) { diff --git a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/InstabugPrivateView.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/InstabugPrivateView.java similarity index 62% rename from packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/InstabugPrivateView.java rename to packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/InstabugPrivateView.java index 9213eadf3..53ed0ac23 100644 --- a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/InstabugPrivateView.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/InstabugPrivateView.java @@ -1,14 +1,11 @@ -package com.instabug.instabug_private_views.modules; +package com.instabug.flutter.modules; -import androidx.annotation.NonNull; +import android.os.Handler; +import android.os.Looper; -import com.instabug.flutter.generated.InstabugLogPigeon; -import com.instabug.flutter.modules.InstabugApi; -import com.instabug.flutter.modules.InstabugLogApi; +import com.instabug.flutter.generated.InstabugPrivateViewPigeon; import com.instabug.flutter.util.privateViews.ScreenshotCaptor; -import com.instabug.instabug_private_views.generated.InstabugPrivateViewPigeon; import com.instabug.library.internal.crossplatform.InternalCore; -import com.instabug.library.screenshot.instacapture.ScreenshotRequest; import io.flutter.plugin.common.BinaryMessenger; @@ -16,24 +13,35 @@ public class InstabugPrivateView implements InstabugPrivateViewPigeon.InstabugPr PrivateViewManager privateViewManager; public static void init(BinaryMessenger messenger, PrivateViewManager privateViewManager) { - final InstabugPrivateView api = new InstabugPrivateView(messenger,privateViewManager); + final InstabugPrivateView api = new InstabugPrivateView(messenger, privateViewManager); InstabugPrivateViewPigeon.InstabugPrivateViewHostApi.setup(messenger, api); } public InstabugPrivateView(BinaryMessenger messenger, PrivateViewManager privateViewManager) { this.privateViewManager = privateViewManager; InstabugPrivateViewPigeon.InstabugPrivateViewHostApi.setup(messenger, this); - + init(); } + static long time = System.currentTimeMillis(); + @Override public void init() { InstabugApi.setScreenshotCaptor(new ScreenshotCaptor() { @Override public void capture(CapturingCallback listener) { - privateViewManager.mask(listener); + + (new Handler(Looper.getMainLooper())).postDelayed(new Runnable() { + @Override + public void run() { + time = System.currentTimeMillis(); + privateViewManager.mask(listener); + + } + }, 300); + } - },InternalCore.INSTANCE); + }, InternalCore.INSTANCE); } } diff --git a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/PrivateViewManager.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/PrivateViewManager.java similarity index 78% rename from packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/PrivateViewManager.java rename to packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/PrivateViewManager.java index 6b8abb152..fd105be5a 100644 --- a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/PrivateViewManager.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/PrivateViewManager.java @@ -1,4 +1,4 @@ -package com.instabug.instabug_private_views.modules; +package com.instabug.flutter.modules; import android.app.Activity; import android.graphics.Bitmap; @@ -9,12 +9,12 @@ import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import com.instabug.flutter.generated.InstabugPrivateViewPigeon; +import com.instabug.flutter.model.ScreenshotResult; +import com.instabug.flutter.modules.capturing.CaptureManager; +import com.instabug.flutter.modules.capturing.ScreenshotResultCallback; import com.instabug.flutter.util.ThreadManager; import com.instabug.flutter.util.privateViews.ScreenshotCaptor; -import com.instabug.instabug_private_views.generated.InstabugPrivateViewPigeon; -import com.instabug.instabug_private_views.model.ScreenshotResult; -import com.instabug.instabug_private_views.modules.capturing.CaptureManager; -import com.instabug.instabug_private_views.modules.capturing.ScreenshotResultCallback; import java.util.List; import java.util.concurrent.CountDownLatch; @@ -85,6 +85,7 @@ public void run() { @Override public void onScreenshotResult(ScreenshotResult result) { processScreenshot(result, privateViews, latch, capturingCallback); + } @Override @@ -113,6 +114,9 @@ private void processScreenshot(ScreenshotResult result, AtomicReference privateViews) { - if (privateViews == null || privateViews.isEmpty()) return; - - Bitmap bitmap = result.getScreenshot(); - float pixelRatio = result.getPixelRatio(); - Canvas canvas = new Canvas(bitmap); - Paint paint = new Paint(); // Default color is black - - for (int i = 0; i < privateViews.size(); i += 4) { - float left = privateViews.get(i).floatValue() * pixelRatio; - float top = privateViews.get(i + 1).floatValue() * pixelRatio; - float right = privateViews.get(i + 2).floatValue() * pixelRatio; - float bottom = privateViews.get(i + 3).floatValue() * pixelRatio; - canvas.drawRect(left, top, right, bottom, paint); // Mask private view + try { + if (privateViews == null || privateViews.isEmpty()) return; + + Bitmap bitmap = result.getScreenshot(); + float pixelRatio = result.getPixelRatio(); + Canvas canvas = new Canvas(bitmap); + Paint paint = new Paint(); // Default color is black + + for (int i = 0; i < privateViews.size(); i += 4) { + float left = privateViews.get(i).floatValue() * pixelRatio; + float top = privateViews.get(i + 1).floatValue() * pixelRatio; + float right = privateViews.get(i + 2).floatValue() * pixelRatio; + float bottom = privateViews.get(i + 3).floatValue() * pixelRatio; + canvas.drawRect(left, top, right, bottom, paint); // Mask private view + } + } catch (Exception e) { + e.printStackTrace(); } } } \ No newline at end of file diff --git a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/BoundryCaptureManager.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/BoundryCaptureManager.java similarity index 91% rename from packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/BoundryCaptureManager.java rename to packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/BoundryCaptureManager.java index 4c9f3d047..6f8409749 100644 --- a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/BoundryCaptureManager.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/BoundryCaptureManager.java @@ -1,12 +1,13 @@ -package com.instabug.instabug_private_views.modules.capturing; +package com.instabug.flutter.modules.capturing; import android.app.Activity; import android.graphics.Bitmap; import android.util.DisplayMetrics; import android.view.View; +import com.instabug.flutter.model.ScreenshotResult; import com.instabug.flutter.util.ThreadManager; -import com.instabug.instabug_private_views.model.ScreenshotResult; + import io.flutter.embedding.engine.renderer.FlutterRenderer; public class BoundryCaptureManager implements CaptureManager { diff --git a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/CaptureManager.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/CaptureManager.java similarity index 71% rename from packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/CaptureManager.java rename to packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/CaptureManager.java index 4b6ccff84..f15aa4780 100644 --- a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/CaptureManager.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/CaptureManager.java @@ -1,4 +1,4 @@ -package com.instabug.instabug_private_views.modules.capturing; +package com.instabug.flutter.modules.capturing; import android.app.Activity; diff --git a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/PixelCopyCaptureManager.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/PixelCopyCaptureManager.java similarity index 96% rename from packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/PixelCopyCaptureManager.java rename to packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/PixelCopyCaptureManager.java index f8f3d2cca..be19f1ca6 100644 --- a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/PixelCopyCaptureManager.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/PixelCopyCaptureManager.java @@ -1,4 +1,4 @@ -package com.instabug.instabug_private_views.modules.capturing; +package com.instabug.flutter.modules.capturing; import android.app.Activity; import android.graphics.Bitmap; @@ -11,7 +11,7 @@ import androidx.annotation.RequiresApi; -import com.instabug.instabug_private_views.model.ScreenshotResult; +import com.instabug.flutter.model.ScreenshotResult; import com.instabug.library.util.memory.MemoryUtils; import io.flutter.embedding.android.FlutterActivity; diff --git a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/ScreenshotResultCallback.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/ScreenshotResultCallback.java similarity index 50% rename from packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/ScreenshotResultCallback.java rename to packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/ScreenshotResultCallback.java index fd6c0f23f..e01b9b95d 100644 --- a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/capturing/ScreenshotResultCallback.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/capturing/ScreenshotResultCallback.java @@ -1,6 +1,7 @@ -package com.instabug.instabug_private_views.modules.capturing; +package com.instabug.flutter.modules.capturing; -import com.instabug.instabug_private_views.model.ScreenshotResult; + +import com.instabug.flutter.model.ScreenshotResult; public interface ScreenshotResultCallback { void onScreenshotResult(ScreenshotResult screenshotResult); diff --git a/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/util/ArgsRegistry.java b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/util/ArgsRegistry.java index 222a72836..2c37e500d 100644 --- a/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/util/ArgsRegistry.java +++ b/packages/instabug_flutter/android/src/main/java/com/instabug/flutter/util/ArgsRegistry.java @@ -9,6 +9,7 @@ import com.instabug.featuresrequest.ActionType; import com.instabug.library.InstabugColorTheme; import com.instabug.library.InstabugCustomTextPlaceHolder.Key; +import com.instabug.library.MaskingType; import com.instabug.library.OnSdkDismissCallback.DismissType; import com.instabug.library.ReproMode; import com.instabug.library.extendedbugreport.ExtendedBugReport; @@ -16,6 +17,7 @@ import com.instabug.library.invocation.InstabugInvocationEvent; import com.instabug.library.invocation.util.InstabugFloatingButtonEdge; import com.instabug.library.invocation.util.InstabugVideoRecordingButtonPosition; +import com.instabug.library.model.StepType; import com.instabug.library.ui.onboarding.WelcomeMessage; import java.util.HashMap; @@ -53,11 +55,20 @@ public T get(Object key) { put("InvocationOption.disablePostSendingDialog", Option.DISABLE_POST_SENDING_DIALOG); }}; + public static final ArgsMap colorThemes = new ArgsMap() {{ put("ColorTheme.light", InstabugColorTheme.InstabugColorThemeLight); put("ColorTheme.dark", InstabugColorTheme.InstabugColorThemeDark); }}; - public static ArgsMap nonFatalExceptionLevel = new ArgsMap() {{ + + public static final ArgsMap autoMasking = new ArgsMap() {{ + put("AutoMasking.labels", MaskingType.LABELS); + put("AutoMasking.textInputs", MaskingType.TEXT_INPUTS); + put("AutoMasking.media", MaskingType.MEDIA); + put("AutoMasking.none", MaskingType.MASK_NOTHING); + }}; + + public static ArgsMap nonFatalExceptionLevel = new ArgsMap() {{ put("NonFatalExceptionLevel.critical", IBGNonFatalException.Level.CRITICAL); put("NonFatalExceptionLevel.error", IBGNonFatalException.Level.ERROR); put("NonFatalExceptionLevel.warning", IBGNonFatalException.Level.WARNING); @@ -206,4 +217,13 @@ public T get(Object key) { put("CustomTextPlaceHolderKey.messagesNotificationAndOthers", Key.CHATS_MULTIPLE_MESSAGE_NOTIFICATION); put("CustomTextPlaceHolderKey.insufficientContentMessage", Key.COMMENT_FIELD_INSUFFICIENT_CONTENT); }}; + + public static final ArgsMap gestureStepType = new ArgsMap() {{ + put("GestureType.swipe", StepType.SWIPE); + put("GestureType.scroll", StepType.SCROLL); + put("GestureType.tap", StepType.TAP); + put("GestureType.pinch", StepType.PINCH); + put("GestureType.longPress", StepType.LONG_PRESS); + put("GestureType.doubleTap", StepType.DOUBLE_TAP); + }}; } diff --git a/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/ArgsRegistryTest.java b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/ArgsRegistryTest.java index 04082b07e..9a35ef83b 100644 --- a/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/ArgsRegistryTest.java +++ b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/ArgsRegistryTest.java @@ -9,6 +9,7 @@ import com.instabug.flutter.util.ArgsRegistry; import com.instabug.library.InstabugColorTheme; import com.instabug.library.InstabugCustomTextPlaceHolder.Key; +import com.instabug.library.MaskingType; import com.instabug.library.OnSdkDismissCallback.DismissType; import com.instabug.library.ReproMode; import com.instabug.library.extendedbugreport.ExtendedBugReport; @@ -166,6 +167,21 @@ public void testExtendedBugReportStates() { } } + @Test + public void testAutoMasking() { + Integer[] values = { + MaskingType.MASK_NOTHING, + MaskingType.MEDIA, + MaskingType.LABELS, + MaskingType.TEXT_INPUTS, + + }; + + for (Integer value : values) { + assertTrue(ArgsRegistry.autoMasking.containsValue(value)); + } + } + @Test public void testReproModes() { Integer[] values = { diff --git a/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/InstabugApiTest.java b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/InstabugApiTest.java index a9c8ba464..762e9bf86 100644 --- a/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/InstabugApiTest.java +++ b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/InstabugApiTest.java @@ -6,8 +6,10 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockConstruction; @@ -30,6 +32,7 @@ import com.instabug.bug.BugReporting; import com.instabug.flutter.generated.InstabugPigeon; import com.instabug.flutter.modules.InstabugApi; +import com.instabug.flutter.util.ArgsRegistry; import com.instabug.flutter.util.GlobalMocks; import com.instabug.flutter.util.MockReflected; import com.instabug.library.Feature; @@ -38,6 +41,7 @@ import com.instabug.library.InstabugCustomTextPlaceHolder; import com.instabug.library.IssueType; import com.instabug.library.LogLevel; +import com.instabug.library.MaskingType; import com.instabug.library.Platform; import com.instabug.library.ReproConfigurations; import com.instabug.library.ReproMode; @@ -654,4 +658,48 @@ public void testSetScreenshotCaptor() { InstabugApi.setScreenshotCaptor(any(), internalCore); verify(internalCore)._setScreenshotCaptor(any(ScreenshotCaptor.class)); } + + @Test + public void testSetUserStepsEnabledGivenTrue() { + boolean isEnabled = true; + + api.setEnableUserSteps(isEnabled); + + mInstabug.verify(() -> Instabug.setTrackingUserStepsState(Feature.State.ENABLED)); + } + + @Test + public void testSetUserStepsEnabledGivenFalse() { + boolean isEnabled = false; + + api.setEnableUserSteps(isEnabled); + + mInstabug.verify(() -> Instabug.setTrackingUserStepsState(Feature.State.DISABLED)); + } + + @Test + public void testLogUserSteps() { + + final String gestureType = "GestureType.tap"; + final String message = "message"; + final String view = "view"; + + api.logUserSteps(gestureType, message,view); + + reflected.verify(() -> MockReflected.addUserStep(anyLong(), eq(ArgsRegistry.gestureStepType.get(gestureType)), eq(message), isNull(), eq(view))); + + } + + @Test + public void testAutoMasking() { + String maskLabel = "AutoMasking.labels"; + String maskTextInputs = "AutoMasking.textInputs"; + String maskMedia = "AutoMasking.media"; + String maskNone = "AutoMasking.none"; + + + api.enableAutoMasking(List.of(maskLabel, maskMedia, maskTextInputs,maskNone)); + + mInstabug.verify(() -> Instabug.setAutoMaskScreenshotsTypes(MaskingType.LABELS,MaskingType.MEDIA,MaskingType.TEXT_INPUTS,MaskingType.MASK_NOTHING)); + } } diff --git a/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/GlobalMocks.java b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/GlobalMocks.java index 0795acf77..4b37a6d6a 100644 --- a/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/GlobalMocks.java +++ b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/GlobalMocks.java @@ -106,6 +106,14 @@ public static void setUp() throws NoSuchMethodException { Method mEndScreenLoadingCP = MockReflected.class.getDeclaredMethod("endScreenLoadingCP", Long.class, Long.class); mEndScreenLoadingCP.setAccessible(true); reflection.when(() -> Reflection.getMethod(Class.forName("com.instabug.apm.APM"), "endScreenLoadingCP", Long.class, Long.class)).thenReturn(mEndScreenLoadingCP); + + + Method mAddUserStepCp = MockReflected.class.getDeclaredMethod("addUserStep", + long.class, String.class, String.class, String.class, String.class); + mAddUserStepCp.setAccessible(true); + reflection.when(() -> Reflection.getMethod(Class.forName("com.instabug.library.Instabug"), "addUserStep", + long.class, String.class, String.class, String.class, String.class)).thenReturn(mAddUserStepCp);; + } public static void close() { diff --git a/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/MockReflected.java b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/MockReflected.java index 42c85664b..f73364b2e 100644 --- a/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/MockReflected.java +++ b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/MockReflected.java @@ -1,10 +1,12 @@ package com.instabug.flutter.util; import android.graphics.Bitmap; + import androidx.annotation.Nullable; import com.instabug.apm.networkinterception.cp.APMCPNetworkLog; import com.instabug.crash.models.IBGNonFatalException; +import com.instabug.library.model.StepType; import org.json.JSONObject; @@ -19,33 +21,46 @@ public class MockReflected { /** * Instabug.reportScreenChange */ - public static void reportScreenChange(Bitmap screenshot, String name) {} + public static void reportScreenChange(Bitmap screenshot, String name) { + } /** * Instabug.setCustomBrandingImage */ - public static void setCustomBrandingImage(Bitmap light, Bitmap dark) {} + public static void setCustomBrandingImage(Bitmap light, Bitmap dark) { + } /** * Instabug.setCurrentPlatform */ - public static void setCurrentPlatform(int platform) {} + public static void setCurrentPlatform(int platform) { + } /** * APMNetworkLogger.log */ - public static void apmNetworkLog(long requestStartTime, long requestDuration, String requestHeaders, String requestBody, long requestBodySize, String requestMethod, String requestUrl, String responseHeaders, String responseBody, String responseBodySize, long statusCode, int responseContentType, String errorMessage, String var18, @Nullable String gqlQueryName, @Nullable String serverErrorMessage, @Nullable APMCPNetworkLog.W3CExternalTraceAttributes w3CExternalTraceAttributes) {} + public static void apmNetworkLog(long requestStartTime, long requestDuration, String requestHeaders, String requestBody, long requestBodySize, String requestMethod, String requestUrl, String responseHeaders, String responseBody, String responseBodySize, long statusCode, int responseContentType, String errorMessage, String var18, @Nullable String gqlQueryName, @Nullable String serverErrorMessage, @Nullable APMCPNetworkLog.W3CExternalTraceAttributes w3CExternalTraceAttributes) { + } /** * CrashReporting.reportException */ - public static void crashReportException(JSONObject exception, boolean isHandled) {} - public static void crashReportException(JSONObject exception, boolean isHandled, Map userAttributes, JSONObject fingerPrint, IBGNonFatalException.Level level) {} + public static void crashReportException(JSONObject exception, boolean isHandled) { + } + + public static void crashReportException(JSONObject exception, boolean isHandled, Map userAttributes, JSONObject fingerPrint, IBGNonFatalException.Level level) { + } + + public static void startUiTraceCP(String screenName, Long microTimeStamp, Long traceId) { + } - public static void startUiTraceCP(String screenName, Long microTimeStamp, Long traceId) {} + public static void reportScreenLoadingCP(Long startTimeStampMicro, Long durationMicro, Long uiTraceId) { + } - public static void reportScreenLoadingCP(Long startTimeStampMicro, Long durationMicro, Long uiTraceId) {} + public static void endScreenLoadingCP(Long timeStampMicro, Long uiTraceId) { + } - public static void endScreenLoadingCP(Long timeStampMicro, Long uiTraceId) {} + public static void addUserStep(long timestamp, @StepType String stepType, String message, String label, String viewType) { + } } diff --git a/packages/instabug_private_views/android/src/test/java/com/instabug/instabug_private_views/BoundryScreenshotCaptorTest.java b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/private_views/BoundryScreenshotCaptorTest.java similarity index 83% rename from packages/instabug_private_views/android/src/test/java/com/instabug/instabug_private_views/BoundryScreenshotCaptorTest.java rename to packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/private_views/BoundryScreenshotCaptorTest.java index 979f6c6c5..a555345e0 100644 --- a/packages/instabug_private_views/android/src/test/java/com/instabug/instabug_private_views/BoundryScreenshotCaptorTest.java +++ b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/private_views/BoundryScreenshotCaptorTest.java @@ -1,8 +1,5 @@ -package com.instabug.instabug_private_views; +package com.instabug.flutter.util.private_views; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.mock; @@ -16,10 +13,10 @@ import android.graphics.Bitmap; import android.os.Looper; -import com.instabug.instabug_private_views.modules.capturing.BoundryCaptureManager; -import com.instabug.instabug_private_views.modules.capturing.CaptureManager; -import com.instabug.instabug_private_views.model.ScreenshotResult; -import com.instabug.instabug_private_views.modules.capturing.ScreenshotResultCallback; +import com.instabug.flutter.model.ScreenshotResult; +import com.instabug.flutter.modules.capturing.BoundryCaptureManager; +import com.instabug.flutter.modules.capturing.CaptureManager; +import com.instabug.flutter.modules.capturing.ScreenshotResultCallback; import org.junit.Before; import org.junit.Test; diff --git a/packages/instabug_private_views/android/src/test/java/com/instabug/instabug_private_views/PixelCopyScreenshotCaptorTest.java b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/private_views/PixelCopyScreenshotCaptorTest.java similarity index 86% rename from packages/instabug_private_views/android/src/test/java/com/instabug/instabug_private_views/PixelCopyScreenshotCaptorTest.java rename to packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/private_views/PixelCopyScreenshotCaptorTest.java index 4841e8506..868712312 100644 --- a/packages/instabug_private_views/android/src/test/java/com/instabug/instabug_private_views/PixelCopyScreenshotCaptorTest.java +++ b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/private_views/PixelCopyScreenshotCaptorTest.java @@ -1,8 +1,5 @@ -package com.instabug.instabug_private_views; +package com.instabug.flutter.util.private_views; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; @@ -17,10 +14,10 @@ import android.os.Looper; import android.view.SurfaceView; -import com.instabug.instabug_private_views.modules.capturing.CaptureManager; -import com.instabug.instabug_private_views.modules.capturing.PixelCopyCaptureManager; -import com.instabug.instabug_private_views.model.ScreenshotResult; -import com.instabug.instabug_private_views.modules.capturing.ScreenshotResultCallback; +import com.instabug.flutter.model.ScreenshotResult; +import com.instabug.flutter.modules.capturing.CaptureManager; +import com.instabug.flutter.modules.capturing.PixelCopyCaptureManager; +import com.instabug.flutter.modules.capturing.ScreenshotResultCallback; import com.instabug.library.util.memory.MemoryUtils; import org.junit.Before; diff --git a/packages/instabug_private_views/android/src/test/java/com/instabug/instabug_private_views/PrivateViewManagerTest.java b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/private_views/PrivateViewManagerTest.java similarity index 84% rename from packages/instabug_private_views/android/src/test/java/com/instabug/instabug_private_views/PrivateViewManagerTest.java rename to packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/private_views/PrivateViewManagerTest.java index e08b3c50d..a996fb8a2 100644 --- a/packages/instabug_private_views/android/src/test/java/com/instabug/instabug_private_views/PrivateViewManagerTest.java +++ b/packages/instabug_flutter/android/src/test/java/com/instabug/flutter/util/private_views/PrivateViewManagerTest.java @@ -1,8 +1,7 @@ -package com.instabug.instabug_private_views; +package com.instabug.flutter.util.private_views; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; @@ -18,13 +17,14 @@ import android.os.Build; import android.os.Looper; import android.view.SurfaceView; -import com.instabug.instabug_private_views.generated.InstabugPrivateViewPigeon; -import com.instabug.instabug_private_views.modules.capturing.BoundryCaptureManager; -import com.instabug.instabug_private_views.modules.capturing.CaptureManager; -import com.instabug.instabug_private_views.modules.capturing.PixelCopyCaptureManager; -import com.instabug.instabug_private_views.modules.PrivateViewManager; -import com.instabug.instabug_private_views.model.ScreenshotResult; -import com.instabug.library.screenshot.ScreenshotCaptor; + +import com.instabug.flutter.generated.InstabugPrivateViewPigeon; +import com.instabug.flutter.model.ScreenshotResult; +import com.instabug.flutter.modules.PrivateViewManager; +import com.instabug.flutter.modules.capturing.BoundryCaptureManager; +import com.instabug.flutter.modules.capturing.CaptureManager; +import com.instabug.flutter.modules.capturing.PixelCopyCaptureManager; +import com.instabug.flutter.util.privateViews.ScreenshotCaptor; import org.junit.Before; import org.junit.Test; @@ -68,7 +68,7 @@ public void setUp() { @Test public void testMaskGivenEmptyActivity() { - ScreenshotCaptor.CapturingCallback capturingCallbackMock = mock(ScreenshotCaptor.CapturingCallback.class); + com.instabug.flutter.util.privateViews.ScreenshotCaptor.CapturingCallback capturingCallbackMock = mock(ScreenshotCaptor.CapturingCallback.class); privateViewManager.setActivity(null); privateViewManager.mask(capturingCallbackMock); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Throwable.class); @@ -78,7 +78,7 @@ public void testMaskGivenEmptyActivity() { @Test public void testMask() throws InterruptedException { - ScreenshotCaptor.CapturingCallback capturingCallbackMock = mock(ScreenshotCaptor.CapturingCallback.class); + com.instabug.flutter.util.privateViews.ScreenshotCaptor.CapturingCallback capturingCallbackMock = mock(com.instabug.flutter.util.privateViews.ScreenshotCaptor.CapturingCallback.class); doAnswer(invocation -> { InstabugPrivateViewPigeon.InstabugPrivateViewFlutterApi.Reply> callback = invocation.getArgument(0); // Get the callback callback.reply(Arrays.asList(10.0, 20.0, 100.0, 200.0)); // Trigger the success callback @@ -134,7 +134,7 @@ public void testMaskShouldGetScreenshotWhenAPIVersionLessThan28() { @Test public void testMaskShouldCallPixelCopyWhenAPIVersionMoreThan28() { - ScreenshotCaptor.CapturingCallback capturingCallbackMock = mock(ScreenshotCaptor.CapturingCallback.class); + com.instabug.flutter.util.privateViews.ScreenshotCaptor.CapturingCallback capturingCallbackMock = mock(com.instabug.flutter.util.privateViews.ScreenshotCaptor.CapturingCallback.class); mockFlutterViewInPixelCopy(); privateViewManager.mask(capturingCallbackMock); shadowOf(Looper.getMainLooper()).idle(); diff --git a/packages/instabug_flutter/example/android/app/build.gradle b/packages/instabug_flutter/example/android/app/build.gradle index 996b39242..f29331c1f 100644 --- a/packages/instabug_flutter/example/android/app/build.gradle +++ b/packages/instabug_flutter/example/android/app/build.gradle @@ -1,54 +1,31 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +plugins { + id "com.android.application" + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" } -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { - compileSdkVersion 34 - ndkVersion flutter.ndkVersion namespace = "com.instabug.flutter.example" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { - jvmTarget = '1.8' - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' + jvmTarget = JavaVersion.VERSION_1_8 } defaultConfig { applicationId "com.instabug.flutter.example" minSdkVersion 21 targetSdkVersion 34 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName + versionCode flutter.versionCode + versionName flutter.versionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true } @@ -57,7 +34,7 @@ android { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug + signingConfig = signingConfigs.debug } } namespace 'com.instabug.flutter.example' @@ -72,7 +49,7 @@ flutter { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.20" implementation 'com.android.support:multidex:1.0.3' implementation 'org.mockito:mockito-core:1.10.19' testImplementation 'junit:junit:4.12' diff --git a/packages/instabug_flutter/example/android/build.gradle b/packages/instabug_flutter/example/android/build.gradle index e7ee2eaf8..6cc62edd7 100644 --- a/packages/instabug_flutter/example/android/build.gradle +++ b/packages/instabug_flutter/example/android/build.gradle @@ -1,24 +1,8 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:8.0.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - rootProject.buildDir = '../build' + +//android { +// namespace 'com.instabug.flutter.example' +//} subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } diff --git a/packages/instabug_flutter/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/instabug_flutter/example/android/gradle/wrapper/gradle-wrapper.properties index 89e56bdb6..4cf0c849a 100644 --- a/packages/instabug_flutter/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/instabug_flutter/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip diff --git a/packages/instabug_flutter/example/android/settings.gradle b/packages/instabug_flutter/example/android/settings.gradle index 8f6a080fc..32cfc43dc 100644 --- a/packages/instabug_flutter/example/android/settings.gradle +++ b/packages/instabug_flutter/example/android/settings.gradle @@ -1,12 +1,27 @@ -rootProject.name = 'InstabugExample' -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + repositories { + google() + mavenCentral() + gradlePluginPortal() + maven { url 'https://storage.googleapis.com/flutter-plugins' } -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "8.1.0" apply false + id "org.jetbrains.kotlin.android" version "1.8.22" apply false +} + +include ":app" diff --git a/packages/instabug_flutter/example/ios/InstabugTests/ArgsRegistryTests.m b/packages/instabug_flutter/example/ios/InstabugTests/ArgsRegistryTests.m index bded153fd..6e346cf33 100644 --- a/packages/instabug_flutter/example/ios/InstabugTests/ArgsRegistryTests.m +++ b/packages/instabug_flutter/example/ios/InstabugTests/ArgsRegistryTests.m @@ -188,6 +188,21 @@ - (void)testLocales { } } +- (void)testUserStepsGesture { + NSArray *values = @[ + @(IBGUIEventTypeSwipe), + @(IBGUIEventTypeScroll), + @(IBGUIEventTypeTap), + @(IBGUIEventTypePinch), + @(IBGUIEventTypeLongPress), + @(IBGUIEventTypeDoubleTap), + ]; + + for (NSNumber *value in values) { + XCTAssertTrue([[ArgsRegistry.userStepsGesture allValues] containsObject:value]); + } +} + - (void)testPlaceholders { NSArray *values = @[ kIBGShakeStartAlertTextStringName, @@ -254,4 +269,17 @@ - (void)testPlaceholders { } } +- (void)testAutoaAsking { + NSArray *values = @[ + @(IBGAutoMaskScreenshotOptionMedia), + @(IBGAutoMaskScreenshotOptionLabels), + @(IBGAutoMaskScreenshotOptionTextInputs), + @(IBGAutoMaskScreenshotOptionMaskNothing) + ]; + + for (NSNumber *value in values) { + XCTAssertTrue([[ArgsRegistry.autoMasking allValues] containsObject:value]); + } +} + @end diff --git a/packages/instabug_flutter/example/ios/InstabugTests/InstabugApiTests.m b/packages/instabug_flutter/example/ios/InstabugTests/InstabugApiTests.m index 7c0cc63dc..755ce9113 100644 --- a/packages/instabug_flutter/example/ios/InstabugTests/InstabugApiTests.m +++ b/packages/instabug_flutter/example/ios/InstabugTests/InstabugApiTests.m @@ -602,4 +602,32 @@ - (void)testisW3CFeatureFlagsEnabled { } +- (void)testSetEnableUserStepsIsEnabled{ + NSNumber *isEnabled = @1; + FlutterError *error; + + [self.api setEnableUserStepsIsEnabled:isEnabled error:&error]; + + OCMVerify([self.mInstabug setTrackUserSteps:YES]); + +} + +- (void)testLogUserStepsGestureType{ + NSString* message = @"message"; + NSString* view = @"viewName"; + FlutterError *error; + + [self.api logUserStepsGestureType:@"GestureType.tap" message:message viewName:view error: &error]; + + XCTAssertNil(error, @"Error should be nil"); + +} +- (void)testAutoMasking { + NSArray *autoMaskingTypes = @[@"AutoMasking.labels", @"AutoMasking.textInputs",@"AutoMasking.media",@"AutoMasking.none"]; + FlutterError *error; + + [self.api enableAutoMaskingAutoMasking:autoMaskingTypes error:&error]; + + OCMVerify([self.mInstabug setAutoMaskScreenshots: (IBGAutoMaskScreenshotOptionMaskNothing | IBGAutoMaskScreenshotOptionTextInputs | IBGAutoMaskScreenshotOptionLabels | IBGAutoMaskScreenshotOptionMedia)]); +} @end diff --git a/packages/instabug_private_views/example/ios/RunnerTests/PrivateViewApiTests.m b/packages/instabug_flutter/example/ios/InstabugTests/PrivateViewApiTests.m similarity index 90% rename from packages/instabug_private_views/example/ios/RunnerTests/PrivateViewApiTests.m rename to packages/instabug_flutter/example/ios/InstabugTests/PrivateViewApiTests.m index 4d7aa8a65..ac3f17efc 100644 --- a/packages/instabug_private_views/example/ios/RunnerTests/PrivateViewApiTests.m +++ b/packages/instabug_flutter/example/ios/InstabugTests/PrivateViewApiTests.m @@ -93,21 +93,6 @@ - (void)testMask_Success { [self waitForExpectationsWithTimeout:1 handler:nil]; } -- (void)testMask_Error { - XCTestExpectation *expectation = [self expectationWithDescription:@"Mask method with error"]; - - UIImage *screenshot = [UIImage new]; - FlutterError *error = [FlutterError errorWithCode:@"ERROR" message:@"Test error" details:nil]; - - OCMStub([self.mockFlutterApi getPrivateViewsWithCompletion:([OCMArg invokeBlockWithArgs:[NSNull null], error, nil])]); - - [self.api mask:screenshot completion:^(UIImage *result) { - XCTAssertEqual(result, screenshot, @"Original screenshot should be returned on error."); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:1 handler:nil]; -} - (void)testGetFlutterViewOrigin_ValidView { UIView *mockView = [[UIView alloc] initWithFrame:CGRectMake(10, 20, 100, 100)]; diff --git a/packages/instabug_private_views/example/ios/RunnerTests/PrivateViewHostApiTests.m b/packages/instabug_flutter/example/ios/InstabugTests/PrivateViewHostApiTests.m similarity index 97% rename from packages/instabug_private_views/example/ios/RunnerTests/PrivateViewHostApiTests.m rename to packages/instabug_flutter/example/ios/InstabugTests/PrivateViewHostApiTests.m index 8cbe328ea..27b2599ec 100644 --- a/packages/instabug_private_views/example/ios/RunnerTests/PrivateViewHostApiTests.m +++ b/packages/instabug_flutter/example/ios/InstabugTests/PrivateViewHostApiTests.m @@ -2,7 +2,7 @@ #import #import #import "PrivateViewApi.h" -#import "instabug_flutter/InstabugApi.h" +#import "InstabugApi.h" #import "PrivateViewHostApi.h" @interface PrivateViewHostApiTests : XCTestCase diff --git a/packages/instabug_flutter/example/ios/Podfile b/packages/instabug_flutter/example/ios/Podfile index be56c059e..509b3e686 100644 --- a/packages/instabug_flutter/example/ios/Podfile +++ b/packages/instabug_flutter/example/ios/Podfile @@ -29,6 +29,8 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! use_modular_headers! + pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/feature-flutter_user_steps-base/14.1.0/Instabug.podspec' + # pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/feature-flutter-private-views-base/14.0.0/Instabug.podspec' flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/instabug_flutter/example/ios/Podfile.lock b/packages/instabug_flutter/example/ios/Podfile.lock index 5dd77dc53..e92e9b23c 100644 --- a/packages/instabug_flutter/example/ios/Podfile.lock +++ b/packages/instabug_flutter/example/ios/Podfile.lock @@ -4,9 +4,6 @@ PODS: - instabug_flutter (14.0.0): - Flutter - Instabug (= 14.1.0) - - instabug_private_views (0.0.1): - - Flutter - - instabug_flutter - OCMock (3.6) - video_player_avfoundation (0.0.1): - Flutter @@ -14,34 +11,32 @@ PODS: DEPENDENCIES: - Flutter (from `Flutter`) + - Instabug (from `https://ios-releases.instabug.com/custom/feature-flutter_user_steps-base/14.1.0/Instabug.podspec`) - instabug_flutter (from `.symlinks/plugins/instabug_flutter/ios`) - - instabug_private_views (from `.symlinks/plugins/instabug_private_views/ios`) - OCMock (= 3.6) - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`) SPEC REPOS: trunk: - - Instabug - OCMock EXTERNAL SOURCES: Flutter: :path: Flutter + Instabug: + :podspec: https://ios-releases.instabug.com/custom/feature-flutter_user_steps-base/14.1.0/Instabug.podspec instabug_flutter: :path: ".symlinks/plugins/instabug_flutter/ios" - instabug_private_views: - :path: ".symlinks/plugins/instabug_private_views/ios" video_player_avfoundation: :path: ".symlinks/plugins/video_player_avfoundation/darwin" SPEC CHECKSUMS: Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - Instabug: 8cbca8974168c815658133e2813f5ac3a36f8e20 - instabug_flutter: a24751dfaedd29475da2af062d3e19d697438f72 - instabug_private_views: df53ff3f1cc842cb686d43e077099d3b36426a7f + Instabug: 8eb6f63f3ac66f062025c15293549ab67150e9f9 + instabug_flutter: 6552acbd6ba0806e02ed478040d7b7e8a6d53121 OCMock: 5ea90566be239f179ba766fd9fbae5885040b992 - video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 + video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b -PODFILE CHECKSUM: bb7a3c60be3b970b608fa878e26d5fadfbeb1157 +PODFILE CHECKSUM: 87a326d297554318d9004349a35d82ffe3f0c228 -COCOAPODS: 1.14.3 +COCOAPODS: 1.16.2 diff --git a/packages/instabug_flutter/example/ios/Runner.xcodeproj/project.pbxproj b/packages/instabug_flutter/example/ios/Runner.xcodeproj/project.pbxproj index 858ba01e5..a6306d879 100644 --- a/packages/instabug_flutter/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/instabug_flutter/example/ios/Runner.xcodeproj/project.pbxproj @@ -17,6 +17,8 @@ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 9D381ECFBB01BD0E978EBDF2 /* Pods_InstabugTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 71679BEC094CFF3474195C2E /* Pods_InstabugTests.framework */; }; + BE2C04382D70E1BE00C40E47 /* PrivateViewHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BE2C04372D70E1BE00C40E47 /* PrivateViewHostApiTests.m */; }; + BE2C04392D70E1BE00C40E47 /* PrivateViewApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BE2C04362D70E1BE00C40E47 /* PrivateViewApiTests.m */; }; CC080E112937B7DB0041170A /* InstabugApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC080E102937B7DB0041170A /* InstabugApiTests.m */; }; CC198C61293E1A21007077C8 /* SurveysApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC198C60293E1A21007077C8 /* SurveysApiTests.m */; }; CC359DB92937720C0067A924 /* ApmApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC359DB82937720C0067A924 /* ApmApiTests.m */; }; @@ -78,6 +80,8 @@ B03C8370EEFE061BDDDA1DA1 /* Pods-InstabugUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InstabugUITests.debug.xcconfig"; path = "Target Support Files/Pods-InstabugUITests/Pods-InstabugUITests.debug.xcconfig"; sourceTree = ""; }; BA5633844585BB93FE7BCCE7 /* Pods-InstabugTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InstabugTests.profile.xcconfig"; path = "Target Support Files/Pods-InstabugTests/Pods-InstabugTests.profile.xcconfig"; sourceTree = ""; }; BE26C80C2BD55575009FECCF /* IBGCrashReporting+CP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "IBGCrashReporting+CP.h"; sourceTree = ""; }; + BE2C04362D70E1BE00C40E47 /* PrivateViewApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrivateViewApiTests.m; sourceTree = ""; }; + BE2C04372D70E1BE00C40E47 /* PrivateViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrivateViewHostApiTests.m; sourceTree = ""; }; BF9025BBD0A6FD7B193E903A /* Pods-InstabugTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InstabugTests.debug.xcconfig"; path = "Target Support Files/Pods-InstabugTests/Pods-InstabugTests.debug.xcconfig"; sourceTree = ""; }; C090017925D9A030006F3DAE /* InstabugTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InstabugTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C090017D25D9A031006F3DAE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -194,6 +198,8 @@ C090017A25D9A031006F3DAE /* InstabugTests */ = { isa = PBXGroup; children = ( + BE2C04362D70E1BE00C40E47 /* PrivateViewApiTests.m */, + BE2C04372D70E1BE00C40E47 /* PrivateViewHostApiTests.m */, CC198C60293E1A21007077C8 /* SurveysApiTests.m */, CC78720A2938D1C5008CB2A5 /* Util */, CC080E102937B7DB0041170A /* InstabugApiTests.m */, @@ -457,6 +463,8 @@ CC080E112937B7DB0041170A /* InstabugApiTests.m in Sources */, CC198C61293E1A21007077C8 /* SurveysApiTests.m in Sources */, CCADBDD8293CFED300AE5EB8 /* BugReportingApiTests.m in Sources */, + BE2C04382D70E1BE00C40E47 /* PrivateViewHostApiTests.m in Sources */, + BE2C04392D70E1BE00C40E47 /* PrivateViewApiTests.m in Sources */, CC9925D9293DFD7F001FD3EE /* RepliesApiTests.m in Sources */, 206286ED2ABD0A1F00925509 /* SessionReplayApiTests.m in Sources */, CC9925D2293DEB0B001FD3EE /* CrashReportingApiTests.m in Sources */, @@ -552,7 +560,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 56S6Q9SA8U; + DEVELOPMENT_TEAM = VF78H8LBT4; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -688,8 +696,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 56S6Q9SA8U; + DEVELOPMENT_TEAM = VF78H8LBT4; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -706,6 +716,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.instabug.InstabugSample; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -720,7 +731,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 56S6Q9SA8U; + DEVELOPMENT_TEAM = VF78H8LBT4; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/packages/instabug_flutter/example/ios/Runner/Info.plist b/packages/instabug_flutter/example/ios/Runner/Info.plist index 4e0eac976..b2d0e1954 100644 --- a/packages/instabug_flutter/example/ios/Runner/Info.plist +++ b/packages/instabug_flutter/example/ios/Runner/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable @@ -22,6 +24,12 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + NSMicrophoneUsageDescription + Instabug needs access to your microphone so you can attach voice notes. + NSPhotoLibraryUsageDescription + Instabug needs access to your photo library so you can attach images. + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -41,13 +49,5 @@ UIViewControllerBasedStatusBarAppearance - NSMicrophoneUsageDescription - Instabug needs access to your microphone so you can attach voice notes. - NSPhotoLibraryUsageDescription - Instabug needs access to your photo library so you can attach images. - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - diff --git a/packages/instabug_flutter/example/lib/main.dart b/packages/instabug_flutter/example/lib/main.dart index abc04e020..aee5a4676 100644 --- a/packages/instabug_flutter/example/lib/main.dart +++ b/packages/instabug_flutter/example/lib/main.dart @@ -1,14 +1,20 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:developer'; import 'dart:io'; -import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:instabug_flutter/instabug_flutter.dart'; -import 'package:instabug_flutter_example/src/screens/private_view_page.dart'; -import 'package:instabug_http_client/instabug_http_client.dart'; +import 'package:instabug_flutter/src/utils/screen_loading/screen_loading_manager.dart'; import 'package:instabug_flutter_example/src/app_routes.dart'; +import 'package:instabug_flutter_example/src/native/instabug_flutter_example_method_channel.dart'; +import 'package:instabug_flutter_example/src/screens/private_view_page.dart'; +import 'package:instabug_flutter_example/src/widget/instabug_button.dart'; +import 'package:instabug_flutter_example/src/widget/instabug_clipboard_input.dart'; +import 'package:instabug_flutter_example/src/widget/instabug_text_field.dart'; import 'package:instabug_flutter_example/src/widget/nested_view.dart'; +import 'package:instabug_flutter_example/src/widget/section_title.dart'; +import 'package:instabug_http_client/instabug_http_client.dart'; import 'package:instabug_flutter_example/src/native/instabug_flutter_example_method_channel.dart'; import 'package:instabug_flutter_example/src/widget/instabug_button.dart'; @@ -18,29 +24,31 @@ import 'package:instabug_flutter/src/utils/screen_loading/screen_loading_manager import 'package:instabug_flutter_example/src/widget/section_title.dart'; -part 'src/screens/crashes_page.dart'; +part 'src/components/fatal_crashes_content.dart'; -part 'src/screens/complex_page.dart'; +part 'src/components/flows_content.dart'; -part 'src/screens/apm_page.dart'; +part 'src/components/network_content.dart'; -part 'src/screens/screen_capture_premature_extension_page.dart'; +part 'src/components/non_fatal_crashes_content.dart'; -part 'src/screens/screen_loading_page.dart'; +part 'src/components/page.dart'; -part 'src/screens/my_home_page.dart'; +part 'src/components/traces_content.dart'; -part 'src/components/fatal_crashes_content.dart'; +part 'src/screens/apm_page.dart'; -part 'src/components/non_fatal_crashes_content.dart'; +part 'src/screens/complex_page.dart'; -part 'src/components/network_content.dart'; +part 'src/screens/crashes_page.dart'; -part 'src/components/page.dart'; +part 'src/screens/my_home_page.dart'; -part 'src/components/traces_content.dart'; +part 'src/screens/screen_capture_premature_extension_page.dart'; -part 'src/components/flows_content.dart'; +part 'src/screens/screen_loading_page.dart'; + +part 'src/screens/user_steps_page.dart'; void main() { runZonedGuarded( @@ -50,15 +58,22 @@ void main() { Instabug.init( token: 'ed6f659591566da19b67857e1b9d40ab', invocationEvents: [InvocationEvent.floatingButton], - debugLogsLevel: LogLevel.verbose, + debugLogsLevel: LogLevel.none, ); + Instabug.setWelcomeMessageMode(WelcomeMessageMode.disabled); + FlutterError.onError = (FlutterErrorDetails details) { Zone.current.handleUncaughtError(details.exception, details.stack!); }; - - runApp(const MyApp()); + runApp( + const InstabugWidget(automasking: [ + AutoMasking.labels, + AutoMasking.textInputs, + AutoMasking.media + ], child: MyApp()), + ); }, CrashReporting.reportCrash, ); diff --git a/packages/instabug_flutter/example/lib/src/app_routes.dart b/packages/instabug_flutter/example/lib/src/app_routes.dart index 9175d5405..d3947ff7b 100644 --- a/packages/instabug_flutter/example/lib/src/app_routes.dart +++ b/packages/instabug_flutter/example/lib/src/app_routes.dart @@ -1,5 +1,6 @@ import 'package:flutter/widgets.dart' show BuildContext; import 'package:instabug_flutter_example/main.dart'; +import 'package:instabug_flutter_example/src/screens/private_view_page.dart'; final appRoutes = { /// ["/"] route name should only be used with [onGenerateRoute:] when no @@ -10,9 +11,12 @@ final appRoutes = { const MyHomePage(title: 'Flutter Demo Home Pag'), CrashesPage.screenName: (BuildContext context) => const CrashesPage(), ComplexPage.screenName: (BuildContext context) => const ComplexPage(), + PrivateViewPage.screenName: (BuildContext context) => const PrivateViewPage(), + ApmPage.screenName: (BuildContext context) => const ApmPage(), ScreenLoadingPage.screenName: (BuildContext context) => const ScreenLoadingPage(), ScreenCapturePrematureExtensionPage.screenName: (BuildContext context) => const ScreenCapturePrematureExtensionPage(), + UserStepsPage.screenName: (BuildContext context) => const UserStepsPage() }; diff --git a/packages/instabug_flutter/example/lib/src/components/fatal_crashes_content.dart b/packages/instabug_flutter/example/lib/src/components/fatal_crashes_content.dart index c262b63a6..71ea2d59c 100644 --- a/packages/instabug_flutter/example/lib/src/components/fatal_crashes_content.dart +++ b/packages/instabug_flutter/example/lib/src/components/fatal_crashes_content.dart @@ -18,10 +18,12 @@ class FatalCrashesContent extends StatelessWidget { mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ - InstabugButton( - text: 'Throw Exception', - onPressed: () => throwUnhandledException( - Exception('This is a generic exception.')), + InstabugPrivateView( + child: InstabugButton( + text: 'Throw Exception', + onPressed: () => throwUnhandledException( + Exception('This is a generic exception.')), + ), ), InstabugButton( text: 'Throw StateError', diff --git a/packages/instabug_flutter/example/lib/src/components/network_content.dart b/packages/instabug_flutter/example/lib/src/components/network_content.dart index 77ac744b2..d531e17bd 100644 --- a/packages/instabug_flutter/example/lib/src/components/network_content.dart +++ b/packages/instabug_flutter/example/lib/src/components/network_content.dart @@ -18,9 +18,11 @@ class _NetworkContentState extends State { Widget build(BuildContext context) { return Column( children: [ - InstabugClipboardInput( - label: 'Endpoint Url', - controller: endpointUrlController, + InstabugPrivateView( + child: InstabugClipboardInput( + label: 'Endpoint Url', + controller: endpointUrlController, + ), ), InstabugButton( text: 'Send Request To Url', diff --git a/packages/instabug_flutter/example/lib/src/components/page.dart b/packages/instabug_flutter/example/lib/src/components/page.dart index de61d4b65..ccb977ce8 100644 --- a/packages/instabug_flutter/example/lib/src/components/page.dart +++ b/packages/instabug_flutter/example/lib/src/components/page.dart @@ -20,7 +20,9 @@ class Page extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( key: scaffoldKey, - appBar: AppBar(title: Text(title)), + appBar: AppBar( + title: Text(title), + ), body: SingleChildScrollView( physics: const ClampingScrollPhysics(), padding: const EdgeInsets.only(top: 20.0), diff --git a/packages/instabug_flutter/example/lib/src/screens/my_home_page.dart b/packages/instabug_flutter/example/lib/src/screens/my_home_page.dart index 4c4b681a3..c3651c5c5 100644 --- a/packages/instabug_flutter/example/lib/src/screens/my_home_page.dart +++ b/packages/instabug_flutter/example/lib/src/screens/my_home_page.dart @@ -170,7 +170,17 @@ class _MyHomePageState extends State { context, MaterialPageRoute( builder: (context) => const PrivateViewPage(), - settings: const RouteSettings(name: ComplexPage.screenName), + settings: const RouteSettings(name: PrivateViewPage.screenName), + ), + ); + } + + void _navigateToUserStepsPage() { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const UserStepsPage(), + settings: const RouteSettings(name: UserStepsPage.screenName), ), ); } @@ -308,9 +318,11 @@ class _MyHomePageState extends State { onPressed: showManualSurvey, text: 'Show Multiple Questions Survey', ), - InstabugButton( - onPressed: showFeatureRequests, - text: 'Show Feature Requests', + InstabugPrivateView( + child: InstabugButton( + onPressed: showFeatureRequests, + text: 'Show Feature Requests', + ), ), InstabugButton( onPressed: _navigateToCrashes, @@ -356,6 +368,10 @@ class _MyHomePageState extends State { ), ], ), + InstabugButton( + text: 'User Steps', + onPressed: _navigateToUserStepsPage, + ), SectionTitle('FeatureFlags'), InstabugTextField( controller: featureFlagsController, diff --git a/packages/instabug_flutter/example/lib/src/screens/private_view_page.dart b/packages/instabug_flutter/example/lib/src/screens/private_view_page.dart index 56a58dacf..a6cca918c 100644 --- a/packages/instabug_flutter/example/lib/src/screens/private_view_page.dart +++ b/packages/instabug_flutter/example/lib/src/screens/private_view_page.dart @@ -1,7 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:instabug_flutter/instabug_flutter.dart'; +import 'package:instabug_flutter_example/src/widget/instabug_button.dart'; +import 'package:instabug_flutter_example/src/widget/section_title.dart'; import 'package:video_player/video_player.dart'; class PrivateViewPage extends StatefulWidget { + static const screenName = 'private'; + const PrivateViewPage({Key? key}) : super(key: key); @override @@ -10,6 +15,23 @@ class PrivateViewPage extends StatefulWidget { class _PrivateViewPageState extends State { late VideoPlayerController _controller; + double _currentSliderValue = 20.0; + + RangeValues _currentRangeValues = const RangeValues(40, 80); + + String? _sliderStatus; + + bool? isChecked = true; + + int? _selectedValue = 1; + + bool light = true; + double _scale = 1.0; // Initial scale of the image + + TextEditingController _controller2 = TextEditingController(); + + String _currentValue = ''; + List _items = List.generate(20, (index) => 'Item ${index + 1}'); @override void initState() { @@ -20,6 +42,11 @@ class _PrivateViewPageState extends State { )..initialize().then((_) { setState(() {}); }); + _controller2.addListener(() { + setState(() { + _currentValue = _controller2.text; + }); + }); } @override @@ -28,18 +55,205 @@ class _PrivateViewPageState extends State { super.dispose(); } + void _handleRadioValueChanged(int? value) { + setState(() { + _selectedValue = value; + }); + } + + int count = 200; + final list = List.generate( + 20, + (_) => InstabugPrivateView( + child: Container( + margin: const EdgeInsets.all(2), + width: 4, + height: 4, + color: Colors.red, + ), + )); @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: const Text("Private Views page")), - body: const SingleChildScrollView( - child: Padding( - padding: EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [], - ), + appBar: AppBar(title: const Text("Private Views page")), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 16), + const InstabugPrivateView( + child: Text( + 'Private TextView', + style: TextStyle(fontSize: 18), + textAlign: TextAlign.center, + ), + ), + const SizedBox(height: 16), + Wrap( + children: list, + ), + const SizedBox(height: 16), + InstabugPrivateView( + child: ElevatedButton( + onPressed: () { + const snackBar = SnackBar( + content: Text('Hello, you clicked on a private button'), + ); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + }, + child: const Text('I am a private button'), + ), + ), + const SizedBox(height: 16), + const BackButton(), + const SectionTitle('TextInput'), + Column( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + // Set the padding value + child: Column( + children: [ + TextField( + key: const Key('text_field'), + controller: _controller2, + // Bind the controller to the TextField + decoration: const InputDecoration( + labelText: + "Type something in a text field with key", + border: OutlineInputBorder(), + ), + ), + InstabugPrivateView( + child: TextField( + controller: _controller2, + // Bind the controller to the TextField + decoration: const InputDecoration( + labelText: "Private view", + border: OutlineInputBorder(), + ), + ), + ), + InstabugPrivateView( + child: TextField( + controller: _controller2, + // Bind the controller to the TextField + obscureText: true, + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: 'Password', + ), + ), + ), + TextFormField( + obscureText: true, + controller: _controller2, + // Bind the controller to the TextField + decoration: const InputDecoration( + icon: Icon(Icons.person), + hintText: 'What do people call you?', + labelText: 'Name *', + ), + onSaved: (String? value) { + // This optional block of code can be used to run + // code when the user saves the form. + }, + validator: (String? value) { + return (value != null && value.contains('@')) + ? 'Do not use the @ char.' + : null; + }, + ), + ], + ), + ), + ], + ), + InstabugPrivateView( + child: Image.asset( + 'assets/img.png', + // Add this image to your assets folder + height: 100, + ), + ), + const SizedBox(height: 33), + const InstabugPrivateView( + child: TextField( + obscureText: true, + decoration: InputDecoration( + hintText: 'password', + labelText: 'Password', + border: OutlineInputBorder(), + ), + ), + ), + const SizedBox(height: 16), + const TextField( + keyboardType: TextInputType.emailAddress, + decoration: InputDecoration( + hintText: 'Email', + labelText: 'Email', + border: OutlineInputBorder(), + ), + ), + const SizedBox(height: 16), + const Column( + children: [ + InstabugPrivateView( + child: Text( + 'Private TextView in column', + style: TextStyle(fontSize: 18), + textAlign: TextAlign.center, + ), + ), + SizedBox( + height: 10, + ), + Text( + 'TextView in column', + style: TextStyle(fontSize: 18), + textAlign: TextAlign.center, + ), + ], + ), + const SizedBox(height: 24), + Container( + height: 300, + child: _controller.value.isInitialized + ? AspectRatio( + aspectRatio: _controller.value.aspectRatio, + child: VideoPlayer(_controller), + ) + : const Center(child: CircularProgressIndicator()), + ), + const SizedBox(height: 24), + const SizedBox(height: 24), + const SizedBox(height: 24), + SizedBox( + height: 200, + child: CustomScrollView( + slivers: [ + InstabugSliverPrivateView( + sliver: SliverToBoxAdapter( + child: Container( + color: Colors.red, + child: const Text( + "Private Sliver Widget", + style: TextStyle(fontSize: 18), + textAlign: TextAlign.center, + ), + ), + ), + ) + ], + ), + ) + ], ), - )); + ), + ), + ); } } diff --git a/packages/instabug_flutter/example/lib/src/screens/user_steps_page.dart b/packages/instabug_flutter/example/lib/src/screens/user_steps_page.dart new file mode 100644 index 000000000..f97cfacc2 --- /dev/null +++ b/packages/instabug_flutter/example/lib/src/screens/user_steps_page.dart @@ -0,0 +1,262 @@ +part of '../../main.dart'; + +class UserStepsPage extends StatefulWidget { + static const screenName = 'user_steps'; + + const UserStepsPage({Key? key}) : super(key: key); + + @override + _UserStepsPageState createState() => _UserStepsPageState(); +} + +class _UserStepsPageState extends State { + double _currentSliderValue = 20.0; + + RangeValues _currentRangeValues = const RangeValues(40, 80); + + String? _sliderStatus; + + bool? isChecked = true; + + int? _selectedValue = 1; + + bool light = true; + double _scale = 1.0; // Initial scale of the image + + TextEditingController _controller = TextEditingController(); + + String _currentValue = ''; + List _items = List.generate(20, (index) => 'Item ${index + 1}'); + + @override + void initState() { + super.initState(); + + _controller.addListener(() { + setState(() { + _currentValue = _controller.text; + }); + }); + } + + void _handleRadioValueChanged(int? value) { + setState(() { + _selectedValue = value; + }); + } + + @override + Widget build(BuildContext context) { + return Page( + title: 'User Steps', + children: [ + BackButton(), + NotificationListener( + onNotification: (ScrollNotification notification) { + return false; + }, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: List.generate( + 100, + (_) => InkWell( + onTap: () {}, + child: Container( + width: 100, + height: 100, + color: Colors.red, + margin: EdgeInsets.all(8), + ), + ), + ), + ), + ), + ), + SectionTitle('Sliders'), + Slider( + value: _currentSliderValue, + max: 100, + divisions: 5, + label: _currentSliderValue.round().toString(), + onChanged: (double value) { + setState(() { + _currentSliderValue = value; + }); + }, + ), + RangeSlider( + values: _currentRangeValues, + max: 100, + divisions: 5, + labels: RangeLabels( + _currentRangeValues.start.round().toString(), + _currentRangeValues.end.round().toString(), + ), + onChanged: (RangeValues values) { + setState(() { + _currentRangeValues = values; + }); + }, + ), + SectionTitle('Images'), + Row( + children: [ + Image.asset( + 'assets/img.png', + height: 100, + ), + Image.network( + "https://t3.ftcdn.net/jpg/00/50/07/64/360_F_50076454_TCvZEw37VyB5ZhcwEjkJHddtuV1cFmKY.jpg", + height: 100, + ), + ], + ), + InstabugButton(text: "I'm a button"), + ElevatedButton(onPressed: () {}, child: Text("data")), + SectionTitle('Toggles'), + Row( + children: [ + Checkbox( + tristate: true, + value: isChecked, + onChanged: (bool? value) { + setState(() { + isChecked = value; + }); + }, + ), + Radio( + value: 0, + groupValue: _selectedValue, + onChanged: _handleRadioValueChanged, + ), + Switch( + value: light, + activeColor: Colors.red, + onChanged: (bool value) { + setState(() { + light = value; + }); + }, + ), + ], + ), + GestureDetector( + onScaleUpdate: (details) { + setState(() { + _scale = details.scale; + _scale = _scale.clamp(1.0, + 3.0); // Limit zoom between 1x and 3x// Update scale based on pinch gesture + }); + }, + onScaleEnd: (details) { + // You can add logic to reset or clamp the scale if needed + if (_scale < 1.0) { + _scale = 1.0; // Prevent shrinking below original size + } + }, + child: Transform.scale( + scale: _scale, // Apply the scale transformation + child: Image.asset( + "assets/img.png", + height: 300, + ), + ), + ), + SectionTitle('TextInput'), + Column( + children: [ + Padding( + padding: EdgeInsets.all(16.0), // Set the padding value + child: Column( + children: [ + TextField( + key: Key('text_field'), + controller: _controller, + // Bind the controller to the TextField + decoration: InputDecoration( + labelText: "Type something in a text field with key", + border: OutlineInputBorder(), + ), + ), + TextField( + controller: _controller, + // Bind the controller to the TextField + decoration: InputDecoration( + labelText: "Private view", + border: OutlineInputBorder(), + ), + ), + TextField( + controller: _controller, + // Bind the controller to the TextField + obscureText: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Password', + ), + ), + TextFormField( + obscureText: true, + controller: _controller, + // Bind the controller to the TextField + decoration: const InputDecoration( + icon: Icon(Icons.person), + hintText: 'What do people call you?', + labelText: 'Name *', + ), + onSaved: (String? value) { + // This optional block of code can be used to run + // code when the user saves the form. + }, + validator: (String? value) { + return (value != null && value.contains('@')) + ? 'Do not use the @ char.' + : null; + }, + ), + ], + ), + ), + ListView.builder( + itemCount: _items.length, + shrinkWrap: true, + itemBuilder: (context, index) { + return Dismissible( + key: Key(_items[index]), + // Unique key for each item + onDismissed: (direction) { + // Remove the item from the list + setState(() { + _items.removeAt(index); + }); + + // Show a snackbar or other UI feedback on dismissal + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Item dismissed')), + ); + }, + background: Container(color: Colors.red), + // Background color when swiped + direction: DismissDirection.endToStart, + // Swipe direction (left to right) + child: ListTile( + title: Text(_items[index]), + ), + ); + }, + ), + ], + ), + ], + ); + } + + @override + void dispose() { + _controller + .dispose(); // Dispose of the controller when the widget is destroyed + super.dispose(); + } +} diff --git a/packages/instabug_flutter/example/lib/src/widget/nested_view.dart b/packages/instabug_flutter/example/lib/src/widget/nested_view.dart index e61099f8c..8ef9e46ad 100644 --- a/packages/instabug_flutter/example/lib/src/widget/nested_view.dart +++ b/packages/instabug_flutter/example/lib/src/widget/nested_view.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:instabug_flutter/instabug_flutter.dart'; import 'package:instabug_flutter_example/main.dart'; class NestedView extends StatelessWidget { @@ -31,10 +32,12 @@ class NestedView extends StatelessWidget { Row( children: List.generate( breadth, - (index) => NestedView( - depth: depth - 1, - breadth: breadth, - child: child, + (index) => InstabugPrivateView( + child: NestedView( + depth: depth - 1, + breadth: breadth, + child: child, + ), ), ), ), diff --git a/packages/instabug_flutter/example/pubspec.lock b/packages/instabug_flutter/example/pubspec.lock index 44060645d..2aaee436d 100644 --- a/packages/instabug_flutter/example/pubspec.lock +++ b/packages/instabug_flutter/example/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" csslib: dependency: transitive description: @@ -118,10 +118,10 @@ packages: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.2" instabug_flutter: dependency: "direct main" description: @@ -136,29 +136,22 @@ packages: relative: true source: path version: "2.4.0" - instabug_private_views: - dependency: "direct overridden" - description: - path: "../../instabug_private_views" - relative: true - source: path - version: "1.0.1" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -235,7 +228,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -248,10 +241,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -264,10 +257,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" sync_http: dependency: transitive description: @@ -288,10 +281,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" typed_data: dependency: transitive description: @@ -312,66 +305,66 @@ packages: dependency: "direct main" description: name: video_player - sha256: "4a8c3492d734f7c39c2588a3206707a05ee80cef52e8c7f3b2078d430c84bc17" + sha256: "48941c8b05732f9582116b1c01850b74dbee1d8520cd7e34ad4609d6df666845" url: "https://pub.dev" source: hosted - version: "2.9.2" + version: "2.9.3" video_player_android: dependency: transitive description: name: video_player_android - sha256: "391e092ba4abe2f93b3e625bd6b6a6ec7d7414279462c1c0ee42b5ab8d0a0898" + sha256: "7018dbcb395e2bca0b9a898e73989e67c0c4a5db269528e1b036ca38bcca0d0b" url: "https://pub.dev" source: hosted - version: "2.7.16" + version: "2.7.17" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation - sha256: cd5ab8a8bc0eab65ab0cea40304097edc46da574c8c1ecdee96f28cd8ef3792f + sha256: "84b4752745eeccb6e75865c9aab39b3d28eb27ba5726d352d45db8297fbd75bc" url: "https://pub.dev" source: hosted - version: "2.6.2" + version: "2.7.0" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface - sha256: "229d7642ccd9f3dc4aba169609dd6b5f3f443bb4cc15b82f7785fcada5af9bbb" + sha256: df534476c341ab2c6a835078066fc681b8265048addd853a1e3c78740316a844 url: "https://pub.dev" source: hosted - version: "6.2.3" + version: "6.3.0" video_player_web: dependency: transitive description: name: video_player_web - sha256: "881b375a934d8ebf868c7fb1423b2bfaa393a0a265fa3f733079a86536064a10" + sha256: "3ef40ea6d72434edbfdba4624b90fd3a80a0740d260667d91e7ecd2d79e13476" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.3.4" vm_service: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" web: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" webdriver: dependency: transitive description: name: webdriver - sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" + sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.4" sdks: - dart: ">=3.5.0 <4.0.0" - flutter: ">=3.24.0" + dart: ">=3.6.0 <4.0.0" + flutter: ">=3.27.0" diff --git a/packages/instabug_flutter/example/pubspec.yaml b/packages/instabug_flutter/example/pubspec.yaml index ec7be1ada..46ab1d7c8 100644 --- a/packages/instabug_flutter/example/pubspec.yaml +++ b/packages/instabug_flutter/example/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: sdk: flutter http: ^0.13.0 instabug_flutter: - path: '../' + path: "../" instabug_http_client: ^2.4.0 video_player: dev_dependencies: @@ -37,7 +37,7 @@ dev_dependencies: dependency_overrides: instabug_flutter: - path: '../' + path: "../" # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -51,7 +51,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - - assets/img.png + - assets/img.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. diff --git a/packages/instabug_flutter/example/pubspec_overrides.yaml b/packages/instabug_flutter/example/pubspec_overrides.yaml new file mode 100644 index 000000000..c41d20248 --- /dev/null +++ b/packages/instabug_flutter/example/pubspec_overrides.yaml @@ -0,0 +1,6 @@ +# melos_managed_dependency_overrides: instabug_flutter,instabug_http_client +dependency_overrides: + instabug_flutter: + path: ../ + instabug_http_client: + path: ../../instabug_http_client diff --git a/packages/instabug_flutter/ios/Classes/InstabugFlutterPlugin.m b/packages/instabug_flutter/ios/Classes/InstabugFlutterPlugin.m index 9b9182ae7..12ab5a58b 100644 --- a/packages/instabug_flutter/ios/Classes/InstabugFlutterPlugin.m +++ b/packages/instabug_flutter/ios/Classes/InstabugFlutterPlugin.m @@ -9,6 +9,8 @@ #import "RepliesApi.h" #import "SessionReplayApi.h" #import "SurveysApi.h" +#import "PrivateViewApi.h" +#import "PrivateViewHostApi.h" @implementation InstabugFlutterPlugin @@ -22,6 +24,9 @@ + (void)registerWithRegistrar:(NSObject *)registrar { InitRepliesApi([registrar messenger]); InitSessionReplayApi([registrar messenger]); InitSurveysApi([registrar messenger]); + PrivateViewApi* privateViewApi = InitPrivateViewApi([registrar messenger],registrar); + InitPrivateViewApi([registrar messenger], registrar); + InitPrivateViewHostApi([registrar messenger], privateViewApi); } @end diff --git a/packages/instabug_flutter/ios/Classes/Modules/InstabugApi.m b/packages/instabug_flutter/ios/Classes/Modules/InstabugApi.m index 84dc9cf3f..f61688876 100644 --- a/packages/instabug_flutter/ios/Classes/Modules/InstabugApi.m +++ b/packages/instabug_flutter/ios/Classes/Modules/InstabugApi.m @@ -55,6 +55,7 @@ - (void)initToken:(NSString *)token invocationEvents:(NSArray *)invo [Instabug setSdkDebugLogsLevel:resolvedLogLevel]; [Instabug startWithToken:token invocationEvents:resolvedEvents]; + Instabug.sendEventsSwizzling = false; } - (void)showWithError:(FlutterError *_Nullable *_Nonnull)error { @@ -393,9 +394,45 @@ - (void)registerFeatureFlagChangeListenerWithError:(FlutterError * _Nullable __a return result; } +- (void)logUserStepsGestureType:(NSString *)gestureType message:(NSString *)message viewName:(NSString *)viewName error:(FlutterError * _Nullable __autoreleasing *)error +{ + @try { + + IBGUIEventType event = ArgsRegistry.userStepsGesture[gestureType].integerValue; + IBGUserStep *userStep = [[IBGUserStep alloc] initWithEvent:event automatic: YES]; + + userStep = [userStep setMessage: message]; + userStep = [userStep setViewTypeName:viewName]; + [userStep logUserStep]; + } + @catch (NSException *exception) { + NSLog(@"%@", exception); + + } +} + + +- (void)setEnableUserStepsIsEnabled:(nonnull NSNumber *)isEnabled error:(FlutterError * _Nullable __autoreleasing * _Nonnull)error { + Instabug.trackUserSteps = isEnabled.boolValue; +} + +- (void)enableAutoMaskingAutoMasking:(nonnull NSArray *)autoMasking error:(FlutterError * _Nullable __autoreleasing * _Nonnull)error { + IBGAutoMaskScreenshotOption resolvedEvents = 0; + + for (NSString *event in autoMasking) { + resolvedEvents |= (ArgsRegistry.autoMasking[event]).integerValue; + } + + [Instabug setAutoMaskScreenshots: resolvedEvents]; + +} + + + + + (void)setScreenshotMaskingHandler:(nullable void (^)(UIImage * _Nonnull __strong, void (^ _Nonnull __strong)(UIImage * _Nonnull __strong)))maskingHandler { - [Instabug setScreenshotMaskingHandler:maskingHandler]; + [Instabug setScreenshotMaskingHandler:maskingHandler]; } @end diff --git a/packages/instabug_private_views/ios/Classes/Modules/PrivateViewApi.h b/packages/instabug_flutter/ios/Classes/Modules/PrivateViewApi.h similarity index 100% rename from packages/instabug_private_views/ios/Classes/Modules/PrivateViewApi.h rename to packages/instabug_flutter/ios/Classes/Modules/PrivateViewApi.h diff --git a/packages/instabug_private_views/ios/Classes/Modules/PrivateViewApi.m b/packages/instabug_flutter/ios/Classes/Modules/PrivateViewApi.m similarity index 84% rename from packages/instabug_private_views/ios/Classes/Modules/PrivateViewApi.m rename to packages/instabug_flutter/ios/Classes/Modules/PrivateViewApi.m index 3b3a8cf7c..be3e988a4 100644 --- a/packages/instabug_private_views/ios/Classes/Modules/PrivateViewApi.m +++ b/packages/instabug_flutter/ios/Classes/Modules/PrivateViewApi.m @@ -1,5 +1,5 @@ #import "PrivateViewApi.h" -#import "FlutterPluginRegistrar+FlutterEngine.h" +#import "../Util/FlutterPluginRegistrar+FlutterEngine.h" extern PrivateViewApi* InitPrivateViewApi( id messenger, @@ -21,19 +21,23 @@ - (instancetype)initWithFlutterApi:(InstabugPrivateViewFlutterApi *)api return self; } +static long long currentTimeMillis; + + - (void)mask:(UIImage *)screenshot completion:(void (^)(UIImage *))completion { __weak typeof(self) weakSelf = self; -// Capture screenshot in parallel - + // Wait for the Cupertino animation to complete + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.flutterApi getPrivateViewsWithCompletion:^(NSArray *rectangles, FlutterError *error) { UIImage *capturedScreenshot = [self captureScreenshot]; - [weakSelf handlePrivateViewsResult:rectangles - error:error - screenshot:capturedScreenshot - completion:completion]; - }]; + [weakSelf handlePrivateViewsResult:rectangles + error:error + screenshot:capturedScreenshot + completion:completion]; + }]; + }); } #pragma mark - Private Methods @@ -66,7 +70,14 @@ - (void)handlePrivateViewsResult:(NSArray *)rectangles NSArray *privateViews = [self convertToRectangles:rectangles]; UIImage *maskedScreenshot = [self drawMaskedImage:screenshot withPrivateViews:privateViews]; + static long long currentTimeMillis2; + currentTimeMillis2 = (long long)([[NSDate date] timeIntervalSince1970] * 1000); + + long long timeDifference = currentTimeMillis2 - currentTimeMillis; + completion(maskedScreenshot); + NSLog(@"Time Difference: %lld ms (Last: %lld, Current: %lld)", timeDifference, currentTimeMillis2, currentTimeMillis); + } diff --git a/packages/instabug_private_views/ios/Classes/Modules/PrivateViewHostApi.h b/packages/instabug_flutter/ios/Classes/Modules/PrivateViewHostApi.h similarity index 100% rename from packages/instabug_private_views/ios/Classes/Modules/PrivateViewHostApi.h rename to packages/instabug_flutter/ios/Classes/Modules/PrivateViewHostApi.h diff --git a/packages/instabug_private_views/ios/Classes/Modules/PrivateViewHostApi.m b/packages/instabug_flutter/ios/Classes/Modules/PrivateViewHostApi.m similarity index 97% rename from packages/instabug_private_views/ios/Classes/Modules/PrivateViewHostApi.m rename to packages/instabug_flutter/ios/Classes/Modules/PrivateViewHostApi.m index 6b1c26c4d..e7dbea5cf 100644 --- a/packages/instabug_private_views/ios/Classes/Modules/PrivateViewHostApi.m +++ b/packages/instabug_flutter/ios/Classes/Modules/PrivateViewHostApi.m @@ -16,8 +16,12 @@ extern void InitPrivateViewHostApi(id _Nonnull messenger @implementation PrivateViewHostApi + - (void)initWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error { [InstabugApi setScreenshotMaskingHandler:^(UIImage * _Nonnull screenshot, void (^ _Nonnull completion)(UIImage * _Nullable)) { + + + [self.privateViewApi mask:screenshot completion:^(UIImage * _Nonnull maskedImage) { if (maskedImage != nil) { completion(maskedImage); diff --git a/packages/instabug_flutter/ios/Classes/Util/ArgsRegistry.h b/packages/instabug_flutter/ios/Classes/Util/ArgsRegistry.h index a465365df..ad94d22d0 100644 --- a/packages/instabug_flutter/ios/Classes/Util/ArgsRegistry.h +++ b/packages/instabug_flutter/ios/Classes/Util/ArgsRegistry.h @@ -18,8 +18,11 @@ typedef NSDictionary ArgsDictionary; + (ArgsDictionary *)extendedBugReportStates; + (ArgsDictionary *)reproModes; + (ArgsDictionary *)nonFatalExceptionLevel; ++ (ArgsDictionary *)autoMasking; + (ArgsDictionary *)locales; ++ (ArgsDictionary *)userStepsGesture; + + (NSDictionary *)placeholders; @end diff --git a/packages/instabug_flutter/ios/Classes/Util/ArgsRegistry.m b/packages/instabug_flutter/ios/Classes/Util/ArgsRegistry.m index 47de80d13..b2e1d6c9f 100644 --- a/packages/instabug_flutter/ios/Classes/Util/ArgsRegistry.m +++ b/packages/instabug_flutter/ios/Classes/Util/ArgsRegistry.m @@ -43,6 +43,18 @@ + (ArgsDictionary *)floatingButtonEdges { }; } ++ (ArgsDictionary *)autoMasking { + return @{ + @"AutoMasking.labels" : @(IBGAutoMaskScreenshotOptionLabels), + @"AutoMasking.textInputs" : @(IBGAutoMaskScreenshotOptionTextInputs), + @"AutoMasking.media" : @(IBGAutoMaskScreenshotOptionMedia), + @"AutoMasking.none" : @(IBGAutoMaskScreenshotOptionMaskNothing +), + + }; +} + + + (ArgsDictionary *)recordButtonPositions { return @{ @"Position.topLeft" : @(IBGPositionTopLeft), @@ -211,4 +223,15 @@ + (ArgsDictionary *)locales { }; } ++ (ArgsDictionary *) userStepsGesture { + return @{ + @"GestureType.swipe" : @(IBGUIEventTypeSwipe), + @"GestureType.scroll" : @(IBGUIEventTypeScroll), + @"GestureType.tap" : @(IBGUIEventTypeTap), + @"GestureType.pinch" : @(IBGUIEventTypePinch), + @"GestureType.longPress" : @(IBGUIEventTypeLongPress), + @"GestureType.doubleTap" : @(IBGUIEventTypeDoubleTap), + }; +} + @end diff --git a/packages/instabug_private_views/ios/Classes/Util/FlutterPluginRegistrar+FlutterEngine.h b/packages/instabug_flutter/ios/Classes/Util/FlutterPluginRegistrar+FlutterEngine.h similarity index 100% rename from packages/instabug_private_views/ios/Classes/Util/FlutterPluginRegistrar+FlutterEngine.h rename to packages/instabug_flutter/ios/Classes/Util/FlutterPluginRegistrar+FlutterEngine.h diff --git a/packages/instabug_private_views/ios/Classes/Util/FlutterPluginRegistrar+FlutterEngine.m b/packages/instabug_flutter/ios/Classes/Util/FlutterPluginRegistrar+FlutterEngine.m similarity index 100% rename from packages/instabug_private_views/ios/Classes/Util/FlutterPluginRegistrar+FlutterEngine.m rename to packages/instabug_flutter/ios/Classes/Util/FlutterPluginRegistrar+FlutterEngine.m diff --git a/packages/instabug_flutter/ios/Classes/Util/Instabug+CP.h b/packages/instabug_flutter/ios/Classes/Util/Instabug+CP.h index 79e988c29..5e1ef85bb 100644 --- a/packages/instabug_flutter/ios/Classes/Util/Instabug+CP.h +++ b/packages/instabug_flutter/ios/Classes/Util/Instabug+CP.h @@ -4,5 +4,6 @@ @interface Instabug (CP) + (void)setScreenshotMaskingHandler:(nullable void (^)(UIImage *, void (^)(UIImage *)))maskingHandler; +@property(nonatomic, assign, class) BOOL sendEventsSwizzling; @end diff --git a/packages/instabug_flutter/ios/instabug_flutter.podspec b/packages/instabug_flutter/ios/instabug_flutter.podspec index f339d7fe0..26b6ea47a 100644 --- a/packages/instabug_flutter/ios/instabug_flutter.podspec +++ b/packages/instabug_flutter/ios/instabug_flutter.podspec @@ -18,5 +18,7 @@ Pod::Spec.new do |s| s.dependency 'Flutter' s.dependency 'Instabug', '14.1.0' + + end diff --git a/packages/instabug_flutter/lib/instabug_flutter.dart b/packages/instabug_flutter/lib/instabug_flutter.dart index e38545897..42c49fc26 100644 --- a/packages/instabug_flutter/lib/instabug_flutter.dart +++ b/packages/instabug_flutter/lib/instabug_flutter.dart @@ -5,7 +5,6 @@ export 'src/models/feature_flag.dart'; export 'src/models/network_data.dart'; export 'src/models/trace.dart'; export 'src/models/w3c_header.dart'; - // Modules export 'src/modules/apm.dart'; export 'src/modules/bug_reporting.dart'; @@ -19,6 +18,11 @@ export 'src/modules/session_replay.dart'; export 'src/modules/surveys.dart'; // Utils export 'src/utils/instabug_navigator_observer.dart'; +export 'src/utils/instabug_widget.dart'; +export 'src/utils/private_views/instabug_private_view.dart'; +export 'src/utils/private_views/instabug_sliver_private_view.dart'; +export 'src/utils/private_views/private_views_manager.dart' show AutoMasking; export 'src/utils/screen_loading/instabug_capture_screen_loading.dart'; export 'src/utils/screen_loading/route_matcher.dart'; export 'src/utils/screen_name_masker.dart' show ScreenNameMaskingCallback; +export 'src/utils/user_steps/instabug_user_steps.dart'; diff --git a/packages/instabug_flutter/lib/src/modules/instabug.dart b/packages/instabug_flutter/lib/src/modules/instabug.dart index 6bba8ed1f..3f9d14770 100644 --- a/packages/instabug_flutter/lib/src/modules/instabug.dart +++ b/packages/instabug_flutter/lib/src/modules/instabug.dart @@ -21,6 +21,7 @@ import 'package:instabug_flutter/src/utils/feature_flags_manager.dart'; import 'package:instabug_flutter/src/utils/ibg_build_info.dart'; import 'package:instabug_flutter/src/utils/instabug_logger.dart'; import 'package:instabug_flutter/src/utils/screen_name_masker.dart'; +import 'package:instabug_flutter/src/utils/user_steps/user_step_details.dart'; import 'package:meta/meta.dart'; enum InvocationEvent { @@ -404,7 +405,9 @@ class Instabug { /// Reports that the screen has been changed (repro steps) /// [screenName] String containing the screen name - static Future reportScreenChange(String screenName) async { + static Future reportScreenChange( + String screenName, + ) async { return _host.reportScreenChange(screenName); } @@ -482,4 +485,20 @@ class Instabug { static Future willRedirectToStore() async { return _host.willRedirectToStore(); } + + /// Enables and disables user interaction steps. + /// [boolean] isEnabled + static Future enableUserSteps(bool isEnabled) async { + return _host.setEnableUserSteps(isEnabled); + } + + /// Enables and disables manual invocation and prompt options for bug and feedback. + /// [boolean] isEnabled + static Future logUserSteps( + GestureType gestureType, + String message, + String? viewName, + ) async { + return _host.logUserSteps(gestureType.toString(), message, viewName); + } } diff --git a/packages/instabug_flutter/lib/src/utils/instabug_navigator_observer.dart b/packages/instabug_flutter/lib/src/utils/instabug_navigator_observer.dart index d9d6b02db..b52ff7892 100644 --- a/packages/instabug_flutter/lib/src/utils/instabug_navigator_observer.dart +++ b/packages/instabug_flutter/lib/src/utils/instabug_navigator_observer.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:instabug_flutter/instabug_flutter.dart'; import 'package:instabug_flutter/src/models/instabug_route.dart'; import 'package:instabug_flutter/src/modules/instabug.dart'; +import 'package:instabug_flutter/src/utils/ibg_build_info.dart'; import 'package:instabug_flutter/src/utils/instabug_logger.dart'; import 'package:instabug_flutter/src/utils/repro_steps_constants.dart'; import 'package:instabug_flutter/src/utils/screen_loading/screen_loading_manager.dart'; @@ -22,22 +23,23 @@ class InstabugNavigatorObserver extends NavigatorObserver { route: newRoute, name: maskedScreenName, ); + //ignore: invalid_null_aware_operator + WidgetsBinding.instance?.addPostFrameCallback((_) async { + // Starts a the new UI trace which is exclusive to screen loading + ScreenLoadingManager.I.startUiTrace(maskedScreenName, screenName); + // If there is a step that hasn't been pushed yet + if (_steps.isNotEmpty) { + await reportScreenChange(_steps.last.name); + // Report the last step and remove it from the list + _steps.removeLast(); + } + + // Add the new step to the list + _steps.add(route); - // Starts a the new UI trace which is exclusive to screen loading - ScreenLoadingManager.I.startUiTrace(maskedScreenName, screenName); - // If there is a step that hasn't been pushed yet - if (_steps.isNotEmpty) { - // Report the last step and remove it from the list - Instabug.reportScreenChange(_steps.last.name); - _steps.removeLast(); - } - - // Add the new step to the list - _steps.add(route); - Future.delayed(const Duration(milliseconds: 1000), () { // If this route is in the array, report it and remove it from the list if (_steps.contains(route)) { - Instabug.reportScreenChange(route.name); + await reportScreenChange(route.name); _steps.remove(route); } }); @@ -47,6 +49,13 @@ class InstabugNavigatorObserver extends NavigatorObserver { } } + Future reportScreenChange(String name) async { + // Wait for the animation to complete + await Future.delayed(const Duration(milliseconds: 100)); + + Instabug.reportScreenChange(name); + } + @override void didPop(Route route, Route? previousRoute) { if (previousRoute != null) { diff --git a/packages/instabug_flutter/lib/src/utils/instabug_widget.dart b/packages/instabug_flutter/lib/src/utils/instabug_widget.dart new file mode 100644 index 000000000..f63ca8776 --- /dev/null +++ b/packages/instabug_flutter/lib/src/utils/instabug_widget.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; +import 'package:instabug_flutter/instabug_flutter.dart'; +import 'package:instabug_flutter/src/generated/instabug_private_view.api.g.dart'; +import 'package:instabug_flutter/src/utils/private_views/private_views_manager.dart'; +import 'package:meta/meta.dart'; + +@internal +final instabugWidgetKey = GlobalKey(debugLabel: 'instabug_screenshot_widget'); + +class InstabugWidget extends StatefulWidget { + final Widget child; + final bool enablePrivateViews; + final bool enableUserSteps; + final List? automasking; + + const InstabugWidget({ + Key? key, + required this.child, + this.enableUserSteps = true, + this.enablePrivateViews = true, + this.automasking, + }) : super(key: key); + + @override + State createState() => _InstabugWidgetState(); +} + +class _InstabugWidgetState extends State { + @override + void initState() { + if (widget.enablePrivateViews) { + _enableInstabugMaskingPrivateViews(); + } + if (widget.automasking != null) { + PrivateViewsManager.I.addAutoMasking(widget.automasking!); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + final child = widget.enableUserSteps + ? InstabugUserSteps(child: widget.child) + : widget.child; + + if (widget.enablePrivateViews) { + return RepaintBoundary( + key: instabugWidgetKey, + child: child, + ); + } + return child; + } +} + +void _enableInstabugMaskingPrivateViews() { + final api = InstabugPrivateViewHostApi(); + api.init(); + InstabugPrivateViewFlutterApi.setup(PrivateViewsManager.I); +} diff --git a/packages/instabug_flutter/lib/src/utils/private_views/instabug_private_view.dart b/packages/instabug_flutter/lib/src/utils/private_views/instabug_private_view.dart new file mode 100644 index 000000000..6903bd47b --- /dev/null +++ b/packages/instabug_flutter/lib/src/utils/private_views/instabug_private_view.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class InstabugPrivateView extends StatelessWidget { + final Widget child; + + const InstabugPrivateView({required this.child, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return child; + } +} diff --git a/packages/instabug_flutter/lib/src/utils/private_views/instabug_sliver_private_view.dart b/packages/instabug_flutter/lib/src/utils/private_views/instabug_sliver_private_view.dart new file mode 100644 index 000000000..1ea626f5a --- /dev/null +++ b/packages/instabug_flutter/lib/src/utils/private_views/instabug_sliver_private_view.dart @@ -0,0 +1,14 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class InstabugSliverPrivateView extends StatelessWidget { + final Widget sliver; + + const InstabugSliverPrivateView({required this.sliver, Key? key}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return sliver; + } +} diff --git a/packages/instabug_flutter/lib/src/utils/private_views/private_views_manager.dart b/packages/instabug_flutter/lib/src/utils/private_views/private_views_manager.dart new file mode 100644 index 000000000..c6a8b1da6 --- /dev/null +++ b/packages/instabug_flutter/lib/src/utils/private_views/private_views_manager.dart @@ -0,0 +1,180 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:instabug_flutter/instabug_flutter.dart'; +import 'package:instabug_flutter/src/generated/instabug.api.g.dart'; +import 'package:instabug_flutter/src/generated/instabug_private_view.api.g.dart'; +import 'package:instabug_flutter/src/utils/enum_converter.dart'; +import 'package:instabug_flutter/src/utils/user_steps/widget_utils.dart'; + +enum AutoMasking { labels, textInputs, media, none } + +extension ValidationMethod on AutoMasking { + bool Function(Widget) hides() { + switch (this) { + case AutoMasking.labels: + return isTextWidget; + case AutoMasking.textInputs: + return isTextInputWidget; + case AutoMasking.media: + return isMedia; + case AutoMasking.none: + return (_) => false; + } + } +} + +/// responsible for masking views +/// before they are sent to the native SDKs. +class PrivateViewsManager implements InstabugPrivateViewFlutterApi { + PrivateViewsManager._() { + _viewChecks = List.of([isPrivateWidget]); + } + + static PrivateViewsManager _instance = PrivateViewsManager._(); + + static PrivateViewsManager get instance => _instance; + static final _host = InstabugHostApi(); + + /// Shorthand for [instance] + static PrivateViewsManager get I => instance; + + @visibleForTesting + // ignore: use_setters_to_change_properties + static void setInstance(PrivateViewsManager instance) { + _instance = instance; + } + + static bool isPrivateWidget(Widget widget) { + final isPrivate = (widget.runtimeType == InstabugPrivateView) || + (widget.runtimeType == InstabugSliverPrivateView); + + return isPrivate; + } + + late List _viewChecks; + + void addAutoMasking(List masking) { + _viewChecks = List.of([isPrivateWidget]); + if (!(masking.contains(AutoMasking.none) && masking.length == 1)) { + _viewChecks.addAll(masking.map((e) => e.hides()).toList()); + } + _host.enableAutoMasking(masking.mapToString()); + } + + Rect? getLayoutRectInfoFromRenderObject(RenderObject? renderObject) { + if (renderObject == null || !renderObject.attached) { + return null; + } + + final globalOffset = _getRenderGlobalOffset(renderObject); + + // Case 1: RenderBox (e.g. Container, Text, etc.) + if (renderObject is RenderBox) { + return renderObject.paintBounds.shift(globalOffset); + } + + // Case 2: RenderSliver (e.g. SliverList, SliverToBoxAdapter, etc.) + if (renderObject is RenderSliver) { + final geometry = renderObject.geometry; + if (geometry == null) { + return null; + } + + final crossAxisExtent = renderObject.constraints.crossAxisExtent; + final paintExtent = geometry.paintExtent; + + return Rect.fromLTWH( + globalOffset.dx, + globalOffset.dy, + // assume vertical scroll by default + crossAxisExtent, + paintExtent, + ); + } + + return null; + } + + // The is the same implementation used in RenderBox.localToGlobal (a subclass of RenderObject) + Offset _getRenderGlobalOffset(RenderObject renderObject) { + // Find the nearest RenderBox ancestor to calculate global position + RenderObject? current = renderObject; + while (current != null && current is! RenderBox) { + final parentNode = current.parent; + if (parentNode is RenderObject) { + current = parentNode; + } else { + current = null; + } + } + + if (current is RenderBox) { + // Get transform from this object to screen root + final transform = renderObject.getTransformTo(null); + return MatrixUtils.transformPoint(transform, Offset.zero); + } + + // fallback: treat as zero offset (shouldn't happen if widget is mounted in tree) + return Offset.zero; + } + + List getRectsOfPrivateViews() { + final context = instabugWidgetKey.currentContext; + if (context == null) return []; + + final rootRenderObject = + context.findRenderObject() as RenderRepaintBoundary?; + if (rootRenderObject is! RenderBox) return []; + + final bounds = Offset.zero & rootRenderObject!.size; + + final rects = []; + + void findPrivateViews(Element element) { + final widget = element.widget; + final isPrivate = _viewChecks.any((e) => e.call(widget)); + if (isPrivate) { + final renderObject = element.findRenderObject(); + if ((renderObject is RenderBox || renderObject is RenderSliver) && + renderObject?.attached == true) { + final isElementInCurrentScreen = isElementInCurrentRoute(element); + final rect = getLayoutRectInfoFromRenderObject(renderObject); + if (rect != null && + rect.overlaps(bounds) && + isElementInCurrentScreen) { + rects.add(rect); + } + } + } else { + element.visitChildElements(findPrivateViews); + } + } + + rects.clear(); + context.visitChildElements(findPrivateViews); + + return rects; + } + + bool isElementInCurrentRoute(Element element) { + final modalRoute = ModalRoute.of(element); + return modalRoute?.isCurrent ?? false; + } + + @override + List getPrivateViews() { + final rects = getRectsOfPrivateViews(); + final result = []; + + for (final rect in rects) { + result.addAll([ + rect.left, + rect.top, + rect.right, + rect.bottom, + ]); + } + + return result; + } +} diff --git a/packages/instabug_flutter/lib/src/utils/user_steps/instabug_user_steps.dart b/packages/instabug_flutter/lib/src/utils/user_steps/instabug_user_steps.dart new file mode 100644 index 000000000..891cd78e2 --- /dev/null +++ b/packages/instabug_flutter/lib/src/utils/user_steps/instabug_user_steps.dart @@ -0,0 +1,261 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:instabug_flutter/instabug_flutter.dart'; +import 'package:instabug_flutter/src/utils/user_steps/user_step_details.dart'; +import 'package:instabug_flutter/src/utils/user_steps/widget_utils.dart'; + +Element? _clickTrackerElement; + +class InstabugUserSteps extends StatefulWidget { + final Widget child; + + const InstabugUserSteps({Key? key, required this.child}) : super(key: key); + + @override + InstabugUserStepsState createState() => InstabugUserStepsState(); + + @override + StatefulElement createElement() { + final element = super.createElement(); + _clickTrackerElement = element; + return element; + } +} + +class InstabugUserStepsState extends State { + static const double _doubleTapThreshold = 300.0; // milliseconds + static const double _pinchSensitivity = 20.0; + static const double _swipeSensitivity = 50.0; + static const double _scrollSensitivity = 50.0; + static const double _tapSensitivity = 20 * 20; + + Timer? _longPressTimer; + Offset? _pointerDownLocation; + GestureType? _gestureType; + String? _gestureMetaData; + DateTime? _lastTapTime; + double _pinchDistance = 0.0; + int _pointerCount = 0; + double? _previousOffset; + + void _onPointerDown(PointerDownEvent event) { + _resetGestureTracking(); + _pointerDownLocation = event.localPosition; + _pointerCount += event.buttons; + _longPressTimer = Timer(const Duration(milliseconds: 500), () { + _gestureType = GestureType.longPress; + }); + } + + void _onPointerUp(PointerUpEvent event, BuildContext context) { + _longPressTimer?.cancel(); + + final gestureType = _detectGestureType(event.localPosition); + if (_gestureType != GestureType.longPress) { + _gestureType = gestureType; + } + + _pointerCount = 0; + + if (_gestureType == null) { + return; + } + final tappedWidget = + _getWidgetDetails(event.localPosition, context, _gestureType!); + if (tappedWidget != null) { + final userStepDetails = tappedWidget.copyWith( + gestureType: _gestureType, + gestureMetaData: _gestureMetaData, + ); + if (userStepDetails.gestureType == null || + userStepDetails.message == null) { + return; + } + + Instabug.logUserSteps( + userStepDetails.gestureType!, + userStepDetails.message!, + userStepDetails.widgetName, + ); + } + } + + GestureType? _detectGestureType(Offset upLocation) { + final delta = upLocation - (_pointerDownLocation ?? Offset.zero); + + if (_pointerCount == 1) { + if (_isTap(delta)) return _detectTapType(); + if (_isSwipe(delta)) return GestureType.swipe; + } else if (_pointerCount == 2 && _isPinch()) { + return GestureType.pinch; + } + + return null; + } + + bool _isTap(Offset delta) => delta.distanceSquared < _tapSensitivity; + + GestureType? _detectTapType() { + final now = DateTime.now(); + final isDoubleTap = _lastTapTime != null && + now.difference(_lastTapTime!).inMilliseconds <= _doubleTapThreshold; + + _lastTapTime = now; + return isDoubleTap ? GestureType.doubleTap : GestureType.tap; + } + + bool _isSwipe(Offset delta) { + final isHorizontal = delta.dx.abs() > delta.dy.abs(); + + if (isHorizontal && delta.dx.abs() > _swipeSensitivity) { + _gestureMetaData = delta.dx > 0 ? "Right" : "Left"; + return true; + } + + if (!isHorizontal && delta.dy.abs() > _swipeSensitivity) { + _gestureMetaData = delta.dy > 0 ? "Down" : "Up"; + return true; + } + + return false; + } + + bool _isPinch() => _pinchDistance.abs() > _pinchSensitivity; + + void _resetGestureTracking() { + _gestureType = null; + _gestureMetaData = null; + _longPressTimer?.cancel(); + } + + UserStepDetails? _getWidgetDetails( + Offset location, + BuildContext context, + GestureType gestureType, + ) { + Element? tappedElement; + var isPrivate = false; + + final rootElement = _clickTrackerElement; + if (rootElement == null || rootElement.widget != widget) return null; + + final hitTestResult = BoxHitTestResult(); + final renderBox = context.findRenderObject()! as RenderBox; + + renderBox.hitTest(hitTestResult, position: _pointerDownLocation!); + + final targets = hitTestResult.path + .where((e) => e.target is RenderBox) + .map((e) => e.target) + .toList(); + + void visitor(Element visitedElement) { + final renderObject = visitedElement.renderObject; + if (renderObject == null) return; + + if (targets.contains(renderObject)) { + final transform = renderObject.getTransformTo(rootElement.renderObject); + final paintBounds = + MatrixUtils.transformRect(transform, renderObject.paintBounds); + + if (paintBounds.contains(_pointerDownLocation!)) { + final widget = visitedElement.widget; + if (!isPrivate) { + isPrivate = widget.runtimeType.toString() == + 'InstabugPrivateView' || + widget.runtimeType.toString() == 'InstabugSliverPrivateView'; + } + if (_isTargetWidget(widget, gestureType)) { + tappedElement = visitedElement; + return; + } + } + } + if (tappedElement == null) { + visitedElement.visitChildElements(visitor); + } + } + + rootElement.visitChildElements(visitor); + if (tappedElement == null) return null; + return UserStepDetails(element: tappedElement, isPrivate: isPrivate); + } + + bool _isTargetWidget(Widget? widget, GestureType type) { + if (widget == null) return false; + switch (type) { + case GestureType.swipe: + return isSwipedWidget(widget); + case GestureType.tap: + case GestureType.longPress: + case GestureType.doubleTap: + return isTappedWidget(widget); + case GestureType.pinch: + return isPinchWidget(widget); + case GestureType.scroll: + return false; + } + } + + void _detectScrollDirection(double currentOffset, Axis direction) { + if (_previousOffset == null) return; + + final delta = (currentOffset - _previousOffset!).abs(); + if (delta < _scrollSensitivity) return; + final String swipeDirection; + if (direction == Axis.horizontal) { + swipeDirection = currentOffset > _previousOffset! ? "Left" : "Right"; + } else { + swipeDirection = currentOffset > _previousOffset! ? "Down" : "Up"; + } + + final userStepDetails = UserStepDetails( + element: null, + isPrivate: false, + gestureMetaData: swipeDirection, + gestureType: GestureType.scroll, + ); + + if (userStepDetails.gestureType == null || + userStepDetails.message == null) { + return; + } + Instabug.logUserSteps( + userStepDetails.gestureType!, + userStepDetails.message!, + "ListView", + ); + } + + @override + Widget build(BuildContext context) { + return Listener( + behavior: HitTestBehavior.translucent, + onPointerDown: _onPointerDown, + onPointerMove: (event) { + if (_pointerCount == 2) { + _pinchDistance = + (event.localPosition - (_pointerDownLocation ?? Offset.zero)) + .distance; + } + }, + onPointerUp: (event) => _onPointerUp(event, context), + child: NotificationListener( + onNotification: (notification) { + if (notification is ScrollStartNotification) { + _previousOffset = notification.metrics.pixels; + } else if (notification is ScrollEndNotification) { + _detectScrollDirection( + notification.metrics.pixels, // Vertical position + notification.metrics.axis, + ); + } + + return true; + }, + child: widget.child, + ), + ); + } +} diff --git a/packages/instabug_flutter/lib/src/utils/user_steps/user_step_details.dart b/packages/instabug_flutter/lib/src/utils/user_steps/user_step_details.dart new file mode 100644 index 000000000..590758eeb --- /dev/null +++ b/packages/instabug_flutter/lib/src/utils/user_steps/user_step_details.dart @@ -0,0 +1,122 @@ +import 'package:flutter/material.dart'; +import 'package:instabug_flutter/src/utils/user_steps/widget_utils.dart'; + +enum GestureType { swipe, scroll, tap, pinch, longPress, doubleTap } + +extension GestureTypeText on GestureType { + String get text { + switch (this) { + case GestureType.swipe: + return "Swiped"; + case GestureType.scroll: + return "Scrolled"; + case GestureType.tap: + return "Tapped"; + case GestureType.pinch: + return "Pinched"; + case GestureType.longPress: + return "Long Pressed"; + case GestureType.doubleTap: + return "Double Tapped"; + } + } +} + +class UserStepDetails { + final Element? element; + final bool isPrivate; + final GestureType? gestureType; + final String? gestureMetaData; + final Widget? widget; + + UserStepDetails({ + required this.element, + required this.isPrivate, + this.gestureType, + this.gestureMetaData, + }) : widget = element?.widget; + + String? get key => widget == null ? null : keyToStringValue(widget!.key); + + String? get widgetName { + if (widget == null) return null; + if (widget is InkWell) { + final inkWell = widget! as InkWell; + if (inkWell.child == null) { + return widget.runtimeType.toString(); + } + return "${inkWell.child.runtimeType} Wrapped with ${widget.runtimeType}"; + } else if (widget is GestureDetector) { + final gestureDetector = widget! as GestureDetector; + + if (gestureDetector.child == null) { + return widget.runtimeType.toString(); + } + return "${gestureDetector.child.runtimeType} Wrapped with ${widget.runtimeType}"; + } + return widget.runtimeType.toString(); + } + + String? get message { + if (gestureType == null) return null; + if (gestureType == GestureType.pinch) { + return gestureType?.text; + } + var baseMessage = ""; + + if (gestureType == GestureType.scroll || gestureType == GestureType.swipe) { + baseMessage += + gestureMetaData?.isNotEmpty == true ? '$gestureMetaData ' : ''; + } + + if (widgetName != null) baseMessage += " $widgetName "; + + if (!isPrivate && widget != null) { + final additionalInfo = _getWidgetSpecificDetails(); + if (additionalInfo != null) baseMessage += additionalInfo; + } + + if (key != null) baseMessage += " with key '$key' "; + + return baseMessage.trimRight(); + } + + String? _getWidgetSpecificDetails() { + if (isSliderWidget(widget!)) { + final value = getSliderValue(widget!); + if (value?.isNotEmpty == true) { + return " to '$value'"; + } + } else if (isTextWidget(widget!) || isButtonWidget(widget!)) { + final label = getLabelRecursively(element!); + if (label?.isNotEmpty == true) { + return "'$label'"; + } + } else if (isToggleableWidget(widget!)) { + final value = getToggleValue(widget!); + if (value?.isNotEmpty == true) { + return " ('$value')"; + } + } else if (isTextInputWidget(widget!)) { + final value = getTextInputValue(widget!); + final hint = getTextHintValue(widget!); + if (value?.isNotEmpty == true) return " '$value'"; + if (hint?.isNotEmpty == true) return "(placeholder:'$hint')"; + } + return null; + } + + UserStepDetails copyWith({ + Element? element, + bool? isPrivate, + GestureType? gestureType, + String? gestureMetaData, + }) { + return UserStepDetails( + element: element ?? this.element, + isPrivate: isPrivate ?? this.isPrivate, + gestureType: gestureType ?? this.gestureType, + gestureMetaData: gestureMetaData ?? this.gestureMetaData, + ); + } +} diff --git a/packages/instabug_flutter/lib/src/utils/user_steps/widget_utils.dart b/packages/instabug_flutter/lib/src/utils/user_steps/widget_utils.dart new file mode 100644 index 000000000..939aa4660 --- /dev/null +++ b/packages/instabug_flutter/lib/src/utils/user_steps/widget_utils.dart @@ -0,0 +1,223 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +/// Converts a [Key] into a string representation, supporting various key types. +String? keyToStringValue(Key? key) { + if (key == null) return null; + + if (key is ValueKey) { + return key.value?.toString(); + } else if (key is GlobalObjectKey) { + return key.value.toString(); + } else if (key is ObjectKey) { + return key.value?.toString(); + } + + return key.toString(); +} + +/// Checks if a widget is a button or button-like component. +bool isButtonWidget(Widget widget) { + if (widget is ButtonStyleButton) return widget.enabled; + if (widget is MaterialButton) return widget.enabled; + if (widget is CupertinoButton) return widget.enabled; + if (widget is IconButton) return widget.onPressed != null; + if (widget is FloatingActionButton) return widget.onPressed != null; + if (widget is BackButton) return widget.onPressed != null; + if (widget is PopupMenuButton) return widget.enabled; + if (widget is DropdownButton) return widget.onTap != null; + + if (widget is GestureDetector) { + return widget.onTap != null || + widget.onLongPress != null || + widget.onDoubleTap != null || + widget.onTapDown != null; + } + + if (widget is InkWell) { + return widget.onTap != null || + widget.onLongPress != null || + widget.onDoubleTap != null || + widget.onTapDown != null; + } + + return false; +} + +/// Checks if a widget can respond to tap-related gestures. +bool isTappedWidget(Widget? widget) { + if (widget == null) return false; + + return isButtonWidget(widget) || + isToggleableWidget(widget) || + isSliderWidget(widget) || + isTextInputWidget(widget); +} + +/// Checks if a widget supports swipe gestures. +bool isSwipedWidget(Widget? widget) { + return widget is Slider || + widget is CupertinoSlider || + widget is RangeSlider || + widget is Dismissible; +} + +/// Determines if a widget supports pinch gestures (defaulting to those not tappable or swipeable). +bool isPinchWidget(Widget? widget) { + return !isSwipedWidget(widget); +} + +/// Checks if a widget is primarily for displaying text. +bool isTextWidget(Widget widget) { + return widget is Text || + widget is RichText || + widget is SelectableText || + widget is TextSpan || + widget is Placeholder || + widget is TextStyle; +} + +/// Checks if a widget is a slider. +bool isSliderWidget(Widget widget) { + return widget is Slider || widget is CupertinoSlider || widget is RangeSlider; +} + +/// Checks if a widget is an image or image-like. +bool isImageWidget(Widget? widget) { + if (widget == null) { + return false; + } + final isDefaultImage = widget is Image || + widget is FadeInImage || + widget is NetworkImage || + widget is AssetImage || + widget is Icon || + widget is FileImage || + widget is MemoryImage || + widget is ImageProvider; + + if (isDefaultImage) { + return true; + } + final imageWidgetTypes = { + 'CachedNetworkImage', // From cached_network_image package + 'SvgPicture', // flutter_svg package + 'OctoImage', // octo_image package + }; + + return imageWidgetTypes.contains(widget.runtimeType.toString()); +} + +bool isVideoPlayerWidget(Widget widget) { + final videoPlayerTypes = { + 'VideoPlayer', // flutter_video_player + 'Chewie', // chewie video player + 'BetterPlayer', // better_player package + 'YoutubePlayer', // youtube_player_flutter + 'VlcPlayer', // flutter_vlc_player + 'FlickVideoPlayer', // flick_video_player + }; + + return videoPlayerTypes.contains(widget.runtimeType.toString()); +} + +bool isMedia(Widget widget) { + return isImageWidget(widget) || isVideoPlayerWidget(widget); +} + +/// Checks if a widget is toggleable (e.g., switch, checkbox, etc.). +bool isToggleableWidget(Widget widget) { + return widget is Checkbox || + widget is CheckboxListTile || + widget is Radio || + widget is RadioListTile || + widget is Switch || + widget is SwitchListTile || + widget is CupertinoSwitch || + widget is ToggleButtons; +} + +/// Checks if a widget is a text input field. +bool isTextInputWidget(Widget widget) { + return widget is TextField || + widget is CupertinoTextField || + widget is EditableText; +} + +/// Retrieves the label of a widget if available. +String? getLabel(Widget widget) { + if (widget is Text) return widget.data; + if (widget is Semantics) return widget.properties.label; + if (widget is Icon) return widget.semanticLabel; + if (widget is Tooltip) return widget.message; + + return null; +} + +/// Retrieves the value of a toggleable widget. +String? getToggleValue(Widget widget) { + bool? value; + if (widget is Checkbox) value = widget.value; + if (widget is Radio) return widget.groupValue.toString(); + if (widget is RadioListTile) return widget.groupValue.toString(); + if (widget is Switch) value = widget.value; + if (widget is SwitchListTile) value = widget.value; + if (widget is CupertinoSwitch) value = widget.value; + if (widget is ToggleButtons) return widget.isSelected.toString(); + + if (value == false || value == null) { + return "UnSelected"; + } else if (value) { + return "Selected"; + } + return null; +} + +/// Retrieves the value entered in a text input field. +String? getTextInputValue(Widget widget) { + if (widget is TextField && !widget.obscureText) { + return widget.controller?.text; + } else if (widget is CupertinoTextField && !widget.obscureText) { + return widget.controller?.text; + } else if (widget is EditableText && !widget.obscureText) { + return widget.controller.text; + } + + return null; +} + +/// Retrieves the hint value of a text input widget. +String? getTextHintValue(Widget widget) { + if (widget is TextField && !widget.obscureText) { + return widget.decoration?.hintText ?? widget.decoration?.labelText; + } else if (widget is CupertinoTextField && !widget.obscureText) { + return widget.placeholder; + } + + return null; +} + +/// Retrieves the current value of a slider widget. +String? getSliderValue(Widget widget) { + if (widget is Slider) return widget.value.toString(); + if (widget is CupertinoSlider) return widget.value.toString(); + if (widget is RangeSlider) { + return "(${widget.values.start},${widget.values.end})"; + } + + return null; +} + +/// Recursively searches for a label within a widget hierarchy. +String? getLabelRecursively(Element element) { + String? label; + + void visitor(Element e) { + label ??= getLabel(e.widget); + if (label == null) e.visitChildren(visitor); + } + + visitor(element); + + return label; +} diff --git a/packages/instabug_flutter/pigeons/instabug.api.dart b/packages/instabug_flutter/pigeons/instabug.api.dart index c0187acb9..337f8a642 100644 --- a/packages/instabug_flutter/pigeons/instabug.api.dart +++ b/packages/instabug_flutter/pigeons/instabug.api.dart @@ -12,39 +12,68 @@ abstract class FeatureFlagsFlutterApi { @HostApi() abstract class InstabugHostApi { void setEnabled(bool isEnabled); + bool isEnabled(); + bool isBuilt(); + void init(String token, List invocationEvents, String debugLogsLevel); + void enableAutoMasking(List autoMasking); + void show(); + void showWelcomeMessageWithMode(String mode); void identifyUser(String email, String? name, String? userId); + void setUserData(String data); + void logUserEvent(String name); + void logOut(); + void setEnableUserSteps(bool isEnabled); + + void logUserSteps( + String gestureType, + String message, + String? viewName, + ); + void setLocale(String locale); + void setColorTheme(String theme); + void setWelcomeMessageMode(String mode); + void setPrimaryColor(int color); + void setSessionProfilerEnabled(bool enabled); + void setValueForStringWithKey(String value, String key); void appendTags(List tags); + void resetTags(); @async List? getTags(); void addExperiments(List experiments); + void removeExperiments(List experiments); + void clearAllExperiments(); + void addFeatureFlags(Map featureFlagsMap); + void removeFeatureFlags(List featureFlags); + void removeAllFeatureFlags(); void setUserAttribute(String value, String key); + void removeUserAttribute(String key); @async @@ -58,13 +87,17 @@ abstract class InstabugHostApi { String? crashMode, String? sessionReplayMode, ); + void reportScreenChange(String screenName); void setCustomBrandingImage(String light, String dark); + void setFont(String font); void addFileAttachmentWithURL(String filePath, String fileName); + void addFileAttachmentWithData(Uint8List data, String fileName); + void clearFileAttachments(); void networkLog(Map data); diff --git a/packages/instabug_private_views/pigeons/instabug_private_view.api.dart b/packages/instabug_flutter/pigeons/instabug_private_view.api.dart similarity index 100% rename from packages/instabug_private_views/pigeons/instabug_private_view.api.dart rename to packages/instabug_flutter/pigeons/instabug_private_view.api.dart diff --git a/packages/instabug_flutter/pubspec.lock b/packages/instabug_flutter/pubspec.lock index 427305640..3134942db 100644 --- a/packages/instabug_flutter/pubspec.lock +++ b/packages/instabug_flutter/pubspec.lock @@ -53,18 +53,18 @@ packages: dependency: transitive description: name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" build_daemon: dependency: transitive description: name: build_daemon - sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" + sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.0.4" build_resolvers: dependency: transitive description: @@ -101,10 +101,10 @@ packages: dependency: transitive description: name: built_value - sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb + sha256: "8b158ab94ec6913e480dc3f752418348b5ae099eb75868b5f4775f0572999c61" url: "https://pub.dev" source: hosted - version: "8.9.2" + version: "8.9.4" characters: dependency: transitive description: @@ -125,10 +125,10 @@ packages: dependency: transitive description: name: cli_util - sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c url: "https://pub.dev" source: hosted - version: "0.4.1" + version: "0.4.2" clock: dependency: transitive description: @@ -141,18 +141,18 @@ packages: dependency: transitive description: name: code_builder - sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" url: "https://pub.dev" source: hosted - version: "4.10.0" + version: "4.10.1" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" convert: dependency: transitive description: @@ -165,10 +165,10 @@ packages: dependency: transitive description: name: coverage - sha256: "88b0fddbe4c92910fefc09cc0248f5e7f0cd23e450ded4c28f16ab8ee8f83268" + sha256: e3493833ea012784c740e341952298f1cc77f1f01b1bbc3eb4eecf6984fb7f43 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.1" crypto: dependency: transitive description: @@ -181,10 +181,10 @@ packages: dependency: transitive description: name: csslib - sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.2" dart_style: dependency: transitive description: @@ -239,10 +239,10 @@ packages: dependency: transitive description: name: glob - sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" graphs: dependency: transitive description: @@ -255,42 +255,42 @@ packages: dependency: transitive description: name: html - sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" url: "https://pub.dev" source: hosted - version: "0.15.4" + version: "0.15.5" http: dependency: transitive description: name: http - sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.3.0" http_multi_server: dependency: transitive description: name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" http_parser: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.2" io: dependency: transitive description: name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" js: dependency: transitive description: @@ -311,18 +311,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -359,10 +359,10 @@ packages: dependency: transitive description: name: markdown - sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051 + sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1" url: "https://pub.dev" source: hosted - version: "7.2.2" + version: "7.3.0" matcher: dependency: transitive description: @@ -415,10 +415,10 @@ packages: dependency: transitive description: name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" pana: dependency: "direct dev" description: @@ -455,18 +455,18 @@ packages: dependency: transitive description: name: pub_semver - sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.5" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.5.0" retry: dependency: transitive description: @@ -487,10 +487,10 @@ packages: dependency: transitive description: name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.2" shelf_packages_handler: dependency: transitive description: @@ -511,15 +511,15 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" sky_engine: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_gen: dependency: transitive description: @@ -540,10 +540,10 @@ packages: dependency: transitive description: name: source_maps - sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" + sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" url: "https://pub.dev" source: hosted - version: "0.10.12" + version: "0.10.13" source_span: dependency: transitive description: @@ -556,10 +556,10 @@ packages: dependency: "direct main" description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -572,18 +572,18 @@ packages: dependency: transitive description: name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" tar: dependency: transitive description: @@ -604,34 +604,34 @@ packages: dependency: transitive description: name: test - sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" + sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f" url: "https://pub.dev" source: hosted - version: "1.25.7" + version: "1.25.8" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" test_core: dependency: transitive description: name: test_core - sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" + sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d" url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" timing: dependency: transitive description: name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.2" typed_data: dependency: transitive description: @@ -652,26 +652,26 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" watcher: dependency: transitive description: name: watcher - sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" web: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" web_socket: dependency: transitive description: @@ -684,10 +684,10 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" webkit_inspection_protocol: dependency: transitive description: @@ -700,10 +700,10 @@ packages: dependency: transitive description: name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.3" sdks: - dart: ">=3.5.0 <4.0.0" + dart: ">=3.6.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/packages/instabug_flutter/test/instabug_test.dart b/packages/instabug_flutter/test/instabug_test.dart index e2fd7d298..1ee67a9d3 100644 --- a/packages/instabug_flutter/test/instabug_test.dart +++ b/packages/instabug_flutter/test/instabug_test.dart @@ -8,6 +8,7 @@ import 'package:instabug_flutter/src/utils/enum_converter.dart'; import 'package:instabug_flutter/src/utils/feature_flags_manager.dart'; import 'package:instabug_flutter/src/utils/ibg_build_info.dart'; import 'package:instabug_flutter/src/utils/screen_name_masker.dart'; +import 'package:instabug_flutter/src/utils/user_steps/user_step_details.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -474,4 +475,26 @@ void main() { mHost.willRedirectToStore(), ).called(1); }); + + test('[enableUserSteps] should call host method', () async { + const enabled = true; + + await Instabug.enableUserSteps(enabled); + + verify( + mHost.setEnableUserSteps(enabled), + ).called(1); + }); + + test('[logUserSteps] should call host method', () async { + const message = "message"; + const gestureType = GestureType.tap; + const viewName = "view"; + + await Instabug.logUserSteps(gestureType, message, viewName); + + verify( + mHost.logUserSteps(gestureType.toString(), message, viewName), + ).called(1); + }); } diff --git a/packages/instabug_flutter/test/utils/instabug_navigator_observer_test.dart b/packages/instabug_flutter/test/utils/instabug_navigator_observer_test.dart index ebf541137..5f138ac8f 100644 --- a/packages/instabug_flutter/test/utils/instabug_navigator_observer_test.dart +++ b/packages/instabug_flutter/test/utils/instabug_navigator_observer_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_null_aware_operator + import 'package:fake_async/fake_async.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -43,8 +45,9 @@ void main() { test('should report screen change when a route is pushed', () { fakeAsync((async) { observer.didPush(route, previousRoute); - - async.elapse(const Duration(milliseconds: 1000)); + WidgetsBinding.instance?.handleBeginFrame(Duration.zero); + WidgetsBinding.instance?.handleDrawFrame(); + async.elapse(const Duration(milliseconds: 2000)); verify( mScreenLoadingManager.startUiTrace(screen, screen), @@ -61,7 +64,8 @@ void main() { () { fakeAsync((async) { observer.didPop(route, previousRoute); - + WidgetsBinding.instance?.handleBeginFrame(Duration.zero); + WidgetsBinding.instance?.handleDrawFrame(); async.elapse(const Duration(milliseconds: 1000)); verify( @@ -79,7 +83,8 @@ void main() { () { fakeAsync((async) { observer.didPop(route, null); - + WidgetsBinding.instance?.handleBeginFrame(Duration.zero); + WidgetsBinding.instance?.handleDrawFrame(); async.elapse(const Duration(milliseconds: 1000)); verifyNever( @@ -98,7 +103,8 @@ void main() { const fallback = 'N/A'; observer.didPush(route, previousRoute); - + WidgetsBinding.instance?.handleBeginFrame(Duration.zero); + WidgetsBinding.instance?.handleDrawFrame(); async.elapse(const Duration(milliseconds: 1000)); verify( @@ -118,8 +124,9 @@ void main() { fakeAsync((async) { observer.didPush(route, previousRoute); - - async.elapse(const Duration(milliseconds: 1000)); + WidgetsBinding.instance?.handleBeginFrame(Duration.zero); + WidgetsBinding.instance?.handleDrawFrame(); + async.elapse(const Duration(milliseconds: 2000)); verify( mScreenLoadingManager.startUiTrace(maskedScreen, screen), diff --git a/packages/instabug_flutter/test/utils/private_views/private_views_manager_test.dart b/packages/instabug_flutter/test/utils/private_views/private_views_manager_test.dart new file mode 100644 index 000000000..ba9b1d5d7 --- /dev/null +++ b/packages/instabug_flutter/test/utils/private_views/private_views_manager_test.dart @@ -0,0 +1,161 @@ +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:instabug_flutter/instabug_flutter.dart'; +import 'package:instabug_flutter/src/utils/private_views/private_views_manager.dart'; + +Future createTestImage() async { + // Create an empty 1x1 image + final recorder = ui.PictureRecorder(); + final canvas = Canvas(recorder); + final paint = Paint()..color = const Color(0xFFFF0000); // Red pixel + canvas.drawRect(const Rect.fromLTWH(0, 0, 1, 1), paint); + + final img = await recorder.endRecording().toImage(1, 1); + final byteData = await img.toByteData(format: ui.ImageByteFormat.png); + return byteData!.buffer.asUint8List(); +} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + WidgetsFlutterBinding.ensureInitialized(); + + group('PrivateViewsManager Tests', () { + late PrivateViewsManager manager; + + setUp(() { + manager = PrivateViewsManager.instance; + }); + + test('isPrivateWidget detects InstabugPrivateView', () { + final widget = InstabugPrivateView(child: Container()); + expect(PrivateViewsManager.isPrivateWidget(widget), isTrue); + }); + + test('isPrivateWidget detects InstabugSliverPrivateView', () { + final widget = InstabugSliverPrivateView(sliver: Container()); + expect(PrivateViewsManager.isPrivateWidget(widget), isTrue); + }); + + test('isPrivateWidget returns false for other widgets', () { + expect(PrivateViewsManager.isPrivateWidget(Container()), isFalse); + expect(PrivateViewsManager.isPrivateWidget(const Text('Hello')), isFalse); + }); + + testWidgets('getRectsOfPrivateViews detects masked views', (tester) async { + await tester.pumpWidget( + InstabugWidget( + child: MaterialApp( + home: Scaffold( + body: ListView( + children: const [ + SizedBox(width: 100, height: 100), + InstabugPrivateView(child: TextField()), + ], + ), + ), + ), + ), + ); + + final rects = manager.getRectsOfPrivateViews(); + expect(rects.length, 1); + }); + + testWidgets('getRectsOfPrivateViews detects masked labels', (tester) async { + await tester.pumpWidget( + InstabugWidget( + automasking: const [AutoMasking.labels], + child: MaterialApp( + home: Scaffold( + body: ListView( + children: const [ + SizedBox(width: 100, height: 100), + Text("Test 1"), + Text("Test 2"), + ], + ), + ), + ), + ), + ); + + final rects = manager.getRectsOfPrivateViews(); + expect(rects.length, 2); + }); + + testWidgets( + 'getPrivateViews returns correct list of masked view coordinates', + (tester) async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: ListView( + children: const [ + InstabugPrivateView( + child: SizedBox(width: 50, height: 50), + ), + ], + ), + ), + ), + ); + + final privateViews = manager.getPrivateViews(); + expect( + privateViews.length % 4, + 0, + ); // Ensure coordinates come in sets of four + }); + + testWidgets('getRectsOfPrivateViews detects masked Media', (tester) async { + final validImage = await tester.runAsync(() => createTestImage()); + + await tester.pumpWidget( + InstabugWidget( + automasking: const [AutoMasking.media], + child: MaterialApp( + home: Scaffold( + body: Column( + children: [ + const SizedBox(width: 100, height: 100), + Image.memory( + validImage!, + ), + ], + ), + ), + ), + ), + ); + + final rects = manager.getRectsOfPrivateViews(); + expect(rects.length, 1); + }); + + testWidgets('getRectsOfPrivateViews detects masked textInputs', + (tester) async { + await tester.pumpWidget( + InstabugWidget( + automasking: const [AutoMasking.textInputs], + child: MaterialApp( + home: Scaffold( + body: ListView( + children: const [ + SizedBox(width: 100, height: 100), + TextField(), + ], + ), + ), + ), + ), + ); + + final rects = manager.getRectsOfPrivateViews(); + expect(rects.length, 1); + }); + }); +} diff --git a/packages/instabug_flutter/test/utils/user_steps/instabug_user_steps_test.dart b/packages/instabug_flutter/test/utils/user_steps/instabug_user_steps_test.dart new file mode 100644 index 000000000..9ac05e4cb --- /dev/null +++ b/packages/instabug_flutter/test/utils/user_steps/instabug_user_steps_test.dart @@ -0,0 +1,298 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:instabug_flutter/instabug_flutter.dart'; +import 'package:instabug_flutter/src/utils/user_steps/user_step_details.dart'; +import 'package:mockito/mockito.dart'; + +import '../../instabug_test.mocks.dart'; + +void main() { + late MockInstabugHostApi mockInstabugHostApi; + + setUp(() { + mockInstabugHostApi = MockInstabugHostApi(); + Instabug.$setHostApi(mockInstabugHostApi); + }); + + Widget buildTestWidget(Widget child) { + return MaterialApp(home: InstabugUserSteps(child: child)); + } + + group('InstabugUserSteps Widget', () { + testWidgets('builds child widget correctly', (tester) async { + await tester.pumpWidget(buildTestWidget(const Text('Test Widget'))); + expect(find.text('Test Widget'), findsOneWidget); + }); + + testWidgets('detects tap gestures', (tester) async { + await tester.pumpWidget( + buildTestWidget( + GestureDetector(onTap: () {}, child: const Text('Tap Me')), + ), + ); + + await tester.tap(find.text('Tap Me')); + await tester.pumpAndSettle(); + + verify( + mockInstabugHostApi.logUserSteps( + GestureType.tap.toString(), + any, + any, + ), + ).called(1); + }); + + testWidgets('detects long press gestures', (tester) async { + await tester.pumpWidget( + buildTestWidget( + GestureDetector( + onLongPress: () {}, + child: const Text('Long Press Me'), + ), + ), + ); + + final gesture = await tester + .startGesture(tester.getCenter(find.text('Long Press Me'))); + await tester + .pump(const Duration(seconds: 2)); // Simulate long press duration + await gesture.up(); + + await tester.pump(); + + verify( + mockInstabugHostApi.logUserSteps( + GestureType.longPress.toString(), + any, + any, + ), + ).called(1); + }); + + group('Swipe Gestures', () { + const scrollOffset = Offset(0, -200); + const smallScrollOffset = Offset(0, -20); + + testWidgets('detects scroll gestures', (tester) async { + await tester.pumpWidget( + buildTestWidget( + ListView(children: List.generate(50, (i) => Text('Item $i'))), + ), + ); + + await tester.fling(find.byType(ListView), scrollOffset, 1000); + await tester.pumpAndSettle(); + + verify( + mockInstabugHostApi.logUserSteps( + GestureType.scroll.toString(), + any, + any, + ), + ).called(1); + }); + + testWidgets('ignores small swipe gestures', (tester) async { + await tester.pumpWidget( + buildTestWidget( + ListView(children: List.generate(50, (i) => Text('Item $i'))), + ), + ); + + await tester.fling(find.byType(ListView), smallScrollOffset, 1000); + await tester.pumpAndSettle(); + + verifyNever( + mockInstabugHostApi.logUserSteps( + GestureType.scroll.toString(), + any, + any, + ), + ); + }); + + testWidgets('detects horizontal scroll', (tester) async { + await tester.pumpWidget( + buildTestWidget( + ListView( + scrollDirection: Axis.horizontal, + children: List.generate(20, (i) => Text('Item $i')), + ), + ), + ); + + await tester.drag(find.byType(ListView), const Offset(-300, 0)); + await tester.pumpAndSettle(); + + verify( + mockInstabugHostApi.logUserSteps( + GestureType.scroll.toString(), + argThat(contains('Left')), + "ListView", + ), + ).called(1); + }); + + testWidgets('detects vertical scroll direction', (tester) async { + await tester.pumpWidget( + buildTestWidget( + ListView(children: List.generate(20, (i) => Text('Item $i'))), + ), + ); + + await tester.drag(find.byType(ListView), const Offset(0, -300)); + await tester.pumpAndSettle(); + + verify( + mockInstabugHostApi.logUserSteps( + GestureType.scroll.toString(), + argThat(contains('Down')), + "ListView", + ), + ).called(1); + }); + + testWidgets('does not log small scroll gestures', (tester) async { + await tester.pumpWidget( + buildTestWidget( + ListView(children: List.generate(20, (i) => Text('Item $i'))), + ), + ); + + await tester.drag(find.byType(ListView), const Offset(0, -10)); + await tester.pumpAndSettle(); + + verifyNever( + mockInstabugHostApi.logUserSteps( + GestureType.scroll.toString(), + argThat(contains('Down')), + "ListView", + ), + ); + }); + }); + + group('Pinch Gestures', () { + testWidgets('handles pinch gestures', (tester) async { + await tester.pumpWidget( + buildTestWidget( + Transform.scale( + scale: 1.0, + child: const Icon(Icons.add, size: 300), + ), + ), + ); + + final iconFinder = find.byIcon(Icons.add); + final pinchStart = tester.getCenter(iconFinder); + + final gesture1 = await tester.startGesture(pinchStart); + final gesture2 = + await tester.startGesture(pinchStart + const Offset(100.0, 0.0)); + + await tester.pump(); + await gesture1.moveTo(pinchStart + const Offset(150.0, 0.0)); + await gesture2.moveTo(pinchStart + const Offset(70.0, 0.0)); + + await gesture1.up(); + await gesture2.up(); + + await tester.pump(const Duration(seconds: 1)); + + verify( + mockInstabugHostApi.logUserSteps( + GestureType.pinch.toString(), + any, + any, + ), + ).called(1); + }); + + testWidgets('ignores small pinch gestures', (tester) async { + await tester.pumpWidget( + buildTestWidget( + Transform.scale( + scale: 1.0, + child: const Icon(Icons.add, size: 300), + ), + ), + ); + + final iconFinder = find.byIcon(Icons.add); + final pinchStart = tester.getCenter(iconFinder); + + final gesture1 = await tester.startGesture(pinchStart); + final gesture2 = + await tester.startGesture(pinchStart + const Offset(100.0, 0.0)); + + await tester.pump(); + await gesture1.moveTo(pinchStart + const Offset(10.0, 0.0)); + await gesture2.moveTo(pinchStart + const Offset(110.0, 0.0)); + + await gesture1.up(); + await gesture2.up(); + + await tester.pump(const Duration(seconds: 1)); + + verifyNever( + mockInstabugHostApi.logUserSteps( + GestureType.pinch.toString(), + any, + any, + ), + ); + }); + }); + + group('Double Tap Gestures', () { + testWidgets('logs double tap gestures', (tester) async { + await tester.pumpWidget( + buildTestWidget( + GestureDetector( + onDoubleTap: () {}, + child: const Text('Double Tap Me'), + ), + ), + ); + + final doubleTapFinder = find.text('Double Tap Me'); + await tester.tap(doubleTapFinder); + await tester.pump(const Duration(milliseconds: 50)); + await tester.tap(doubleTapFinder); + await tester.pumpAndSettle(); + + verify( + mockInstabugHostApi.logUserSteps( + GestureType.doubleTap.toString(), + any, + any, + ), + ).called(1); + }); + + testWidgets('does not log single taps as double taps', (tester) async { + await tester.pumpWidget( + buildTestWidget( + GestureDetector( + onDoubleTap: () {}, + child: const Text('Double Tap Me'), + ), + ), + ); + + final doubleTapFinder = find.text('Double Tap Me'); + await tester.tap(doubleTapFinder); + await tester.pump(const Duration(milliseconds: 50)); + + verifyNever( + mockInstabugHostApi.logUserSteps( + GestureType.doubleTap.toString(), + any, + any, + ), + ); + }); + }); + }); +} diff --git a/packages/instabug_flutter/test/utils/user_steps/user_step_details_test.dart b/packages/instabug_flutter/test/utils/user_steps/user_step_details_test.dart new file mode 100644 index 000000000..0d992755f --- /dev/null +++ b/packages/instabug_flutter/test/utils/user_steps/user_step_details_test.dart @@ -0,0 +1,130 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:instabug_flutter/src/utils/user_steps/user_step_details.dart'; + +void main() { + group('GestureTypeText Extension', () { + test('GestureType.text returns correct text', () { + expect(GestureType.swipe.text, 'Swiped'); + expect(GestureType.scroll.text, 'Scrolled'); + expect(GestureType.tap.text, 'Tapped'); + expect(GestureType.pinch.text, 'Pinched'); + expect(GestureType.longPress.text, 'Long Pressed'); + expect(GestureType.doubleTap.text, 'Double Tapped'); + }); + }); + + group('UserStepDetails', () { + test('key returns correct value', () { + final widget = Container(key: const ValueKey('testKey')); + final element = widget.createElement(); + final details = UserStepDetails( + element: element, + isPrivate: false, + ); + + expect(details.key, 'testKey'); + }); + + test('widgetName identifies widget types correctly', () { + const inkWell = InkWell( + child: Text('Child'), + ); + final detailsInkWell = UserStepDetails( + element: inkWell.createElement(), + isPrivate: false, + ); + expect(detailsInkWell.widgetName, "Text Wrapped with InkWell"); + + final gestureDetector = GestureDetector( + child: const Icon(Icons.add), + ); + final detailsGestureDetector = UserStepDetails( + element: gestureDetector.createElement(), + isPrivate: false, + ); + expect( + detailsGestureDetector.widgetName, + "Icon Wrapped with GestureDetector", + ); + }); + + test('message constructs correctly with gestureType', () { + final widget = Container(key: const ValueKey('testKey')); + final element = widget.createElement(); + + final details = UserStepDetails( + element: element, + isPrivate: false, + gestureType: GestureType.tap, + ); + + expect( + details.message, + " Container with key 'testKey'", + ); + }); + + test('_getWidgetSpecificDetails handles slider widgets', () { + final slider = Slider(value: 0.5, onChanged: (_) {}); + final element = slider.createElement(); + + final details = UserStepDetails( + element: element, + isPrivate: false, + gestureType: GestureType.tap, + ); + + expect( + details.message, + contains(" Slider to '0.5'"), + ); + }); + + test('_getWidgetSpecificDetails handles null widget gracefully', () { + final details = UserStepDetails( + element: null, + isPrivate: false, + ); + + expect(details.message, isNull); + }); + + test('widgetName handles null child gracefully in InkWell', () { + const inkWell = InkWell(); + final details = UserStepDetails( + element: inkWell.createElement(), + isPrivate: false, + ); + expect(details.widgetName, "InkWell"); + }); + + test('message includes additional metadata when gestureMetaData is empty', + () { + final widget = Container(key: const ValueKey('testKey')); + final element = widget.createElement(); + + final details = UserStepDetails( + element: element, + isPrivate: false, + gestureType: GestureType.tap, + gestureMetaData: '', + ); + + expect( + details.message, + " Container with key 'testKey'", + ); + }); + + test('widgetName handles GestureDetector without child', () { + final gestureDetector = GestureDetector(); + final details = UserStepDetails( + element: gestureDetector.createElement(), + isPrivate: false, + ); + expect(details.widgetName, "GestureDetector"); + }); + }); +// }); +} diff --git a/packages/instabug_flutter/test/utils/user_steps/widget_utils_test.dart b/packages/instabug_flutter/test/utils/user_steps/widget_utils_test.dart new file mode 100644 index 000000000..631d49c61 --- /dev/null +++ b/packages/instabug_flutter/test/utils/user_steps/widget_utils_test.dart @@ -0,0 +1,111 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:instabug_flutter/src/utils/user_steps/widget_utils.dart'; + +void main() { + group('keyToStringValue', () { + test('returns null for null key', () { + expect(keyToStringValue(null), isNull); + }); + + test('returns value for ValueKey', () { + expect(keyToStringValue(const ValueKey('test')), 'test'); + }); + + test('returns value for GlobalObjectKey', () { + const globalKey = GlobalObjectKey('globalKey'); + expect(keyToStringValue(globalKey), 'globalKey'); + }); + + test('returns value for ObjectKey', () { + expect(keyToStringValue(const ObjectKey('objectKey')), 'objectKey'); + }); + + test('returns toString for unknown key type', () { + const customKey = Key('customKey'); + expect(keyToStringValue(customKey), 'customKey'); + }); + }); + + group('isButtonWidget', () { + test('detects ButtonStyleButton', () { + final button = + ElevatedButton(onPressed: () {}, child: const Text('Button')); + expect(isButtonWidget(button), true); + }); + + test('detects disabled MaterialButton', () { + const button = MaterialButton(onPressed: null); + expect(isButtonWidget(button), false); + }); + + test('detects IconButton with onPressed', () { + final button = IconButton(onPressed: () {}, icon: const Icon(Icons.add)); + expect(isButtonWidget(button), true); + }); + + test('returns false for non-button widget', () { + const widget = Text('Not a button'); + expect(isButtonWidget(widget), false); + }); + }); + + group('isTappedWidget', () { + test('detects button widget', () { + final button = + ElevatedButton(onPressed: () {}, child: const Text('Button')); + expect(isTappedWidget(button), true); + }); + + test('returns false for null widget', () { + expect(isTappedWidget(null), false); + }); + }); + + group('isTextWidget', () { + test('detects Text widget', () { + const widget = Text('Hello'); + expect(isTextWidget(widget), true); + }); + + test('returns false for non-text widget', () { + const widget = Icon(Icons.add); + expect(isTextWidget(widget), false); + }); + }); + + group('getLabel', () { + test('returns label from Text widget', () { + const widget = Text('Label'); + expect(getLabel(widget), 'Label'); + }); + + test('returns label from Tooltip', () { + const widget = Tooltip(message: 'Tooltip message', child: Text('Child')); + expect(getLabel(widget), 'Tooltip message'); + }); + + test('returns null for unlabeled widget', () { + const widget = Icon(Icons.add); + expect(getLabel(widget), isNull); + }); + }); + + group('getSliderValue', () { + test('returns value from Slider', () { + final widget = Slider(value: 0.5, onChanged: (_) {}); + expect(getSliderValue(widget), '0.5'); + }); + + test('returns value from RangeSlider', () { + final widget = + RangeSlider(values: const RangeValues(0.2, 0.8), onChanged: (_) {}); + expect(getSliderValue(widget), '(0.2,0.8)'); + }); + + test('returns null for non-slider widget', () { + const widget = Text('Not a slider'); + expect(getSliderValue(widget), isNull); + }); + }); +} diff --git a/packages/instabug_flutter_modular/example/pubspec.lock b/packages/instabug_flutter_modular/example/pubspec.lock index aee784432..3f5e6fbd0 100644 --- a/packages/instabug_flutter_modular/example/pubspec.lock +++ b/packages/instabug_flutter_modular/example/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" cupertino_icons: dependency: "direct main" description: @@ -109,18 +109,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -189,7 +189,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -202,10 +202,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -218,10 +218,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" term_glyph: dependency: transitive description: @@ -234,10 +234,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" vector_math: dependency: transitive description: @@ -250,10 +250,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" sdks: - dart: ">=3.3.0 <4.0.0" + dart: ">=3.4.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/packages/instabug_flutter_modular/example/pubspec_overrides.yaml b/packages/instabug_flutter_modular/example/pubspec_overrides.yaml new file mode 100644 index 000000000..82c9b8e03 --- /dev/null +++ b/packages/instabug_flutter_modular/example/pubspec_overrides.yaml @@ -0,0 +1,6 @@ +# melos_managed_dependency_overrides: instabug_flutter,instabug_flutter_modular +dependency_overrides: + instabug_flutter: + path: ../../instabug_flutter + instabug_flutter_modular: + path: .. diff --git a/packages/instabug_flutter_modular/pubspec.lock b/packages/instabug_flutter_modular/pubspec.lock index 92e83db90..5a8fb0853 100644 --- a/packages/instabug_flutter_modular/pubspec.lock +++ b/packages/instabug_flutter_modular/pubspec.lock @@ -5,23 +5,23 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 + sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" url: "https://pub.dev" source: hosted - version: "72.0.0" + version: "76.0.0" _macros: dependency: transitive description: dart source: sdk - version: "0.3.2" + version: "0.3.3" analyzer: dependency: transitive description: name: analyzer - sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 + sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" url: "https://pub.dev" source: hosted - version: "6.7.0" + version: "6.11.0" args: dependency: transitive description: @@ -154,10 +154,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" convert: dependency: transitive description: @@ -347,18 +347,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -387,10 +387,10 @@ packages: dependency: transitive description: name: macros - sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" url: "https://pub.dev" source: hosted - version: "0.1.2-main.4" + version: "0.1.3-main.0" markdown: dependency: transitive description: @@ -563,7 +563,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_gen: dependency: transitive description: @@ -600,10 +600,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -624,10 +624,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" tar: dependency: transitive description: @@ -648,26 +648,26 @@ packages: dependency: transitive description: name: test - sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" + sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f" url: "https://pub.dev" source: hosted - version: "1.25.7" + version: "1.25.8" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" test_core: dependency: transitive description: name: test_core - sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" + sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d" url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" timing: dependency: transitive description: @@ -696,10 +696,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" watcher: dependency: transitive description: diff --git a/packages/instabug_private_views/pubspec_overrides.yaml b/packages/instabug_flutter_modular/pubspec_overrides.yaml similarity index 100% rename from packages/instabug_private_views/pubspec_overrides.yaml rename to packages/instabug_flutter_modular/pubspec_overrides.yaml diff --git a/packages/instabug_flutter_ndk/.gitignore b/packages/instabug_flutter_ndk/.gitignore new file mode 100644 index 000000000..e7d347d9d --- /dev/null +++ b/packages/instabug_flutter_ndk/.gitignore @@ -0,0 +1,33 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# 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 +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +build/ diff --git a/packages/instabug_private_views/.metadata b/packages/instabug_flutter_ndk/.metadata similarity index 61% rename from packages/instabug_private_views/.metadata rename to packages/instabug_flutter_ndk/.metadata index 97e8389f1..165213e45 100644 --- a/packages/instabug_private_views/.metadata +++ b/packages/instabug_flutter_ndk/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: "603104015dd692ea3403755b55d07813d5cf8965" + revision: "09de023485e95e6d1225c2baa44b8feb85e0d45f" channel: "stable" project_type: plugin @@ -13,14 +13,14 @@ project_type: plugin migration: platforms: - platform: root - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + create_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f + base_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f - platform: android - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + create_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f + base_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f - platform: ios - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + create_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f + base_revision: 09de023485e95e6d1225c2baa44b8feb85e0d45f # User provided section diff --git a/packages/instabug_flutter_ndk/CHANGELOG.md b/packages/instabug_flutter_ndk/CHANGELOG.md new file mode 100644 index 000000000..41cc7d819 --- /dev/null +++ b/packages/instabug_flutter_ndk/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/packages/instabug_flutter_ndk/LICENSE b/packages/instabug_flutter_ndk/LICENSE new file mode 100644 index 000000000..ba75c69f7 --- /dev/null +++ b/packages/instabug_flutter_ndk/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/packages/instabug_flutter_ndk/README.md b/packages/instabug_flutter_ndk/README.md new file mode 100644 index 000000000..8280871a0 --- /dev/null +++ b/packages/instabug_flutter_ndk/README.md @@ -0,0 +1,15 @@ +# instabug_flutter_ndk + +Instabug NDK Crash monitoring for Flutter + +## Getting Started + +This project is a starting point for a Flutter +[plug-in package](https://flutter.dev/to/develop-plugins), +a specialized package that includes platform-specific implementation code for +Android and/or iOS. + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev), which offers tutorials, +samples, guidance on mobile development, and a full API reference. + diff --git a/packages/instabug_flutter_ndk/analysis_options.yaml b/packages/instabug_flutter_ndk/analysis_options.yaml new file mode 100644 index 000000000..a5744c1cf --- /dev/null +++ b/packages/instabug_flutter_ndk/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/instabug_flutter_ndk/android/.gitignore b/packages/instabug_flutter_ndk/android/.gitignore new file mode 100644 index 000000000..161bdcdaf --- /dev/null +++ b/packages/instabug_flutter_ndk/android/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.cxx diff --git a/packages/instabug_private_views/android/build.gradle b/packages/instabug_flutter_ndk/android/build.gradle similarity index 64% rename from packages/instabug_private_views/android/build.gradle rename to packages/instabug_flutter_ndk/android/build.gradle index 50025559f..9e06862ba 100644 --- a/packages/instabug_private_views/android/build.gradle +++ b/packages/instabug_flutter_ndk/android/build.gradle @@ -1,4 +1,4 @@ -group = "com.instabug.instabug_private_views" +group = "com.instabug.instabug_flutter_ndk" version = "1.0" buildscript { @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath("com.android.tools.build:gradle:8.1.0") + classpath("com.android.tools.build:gradle:8.7.0") } } @@ -21,16 +21,16 @@ rootProject.allprojects { apply plugin: "com.android.library" +apply from: './native.gradle' + android { - if (project.android.hasProperty("namespace")) { - namespace = "com.instabug.instabug_private_views" - } + namespace = "com.instabug.instabug_flutter_ndk" - compileSdk = 34 + compileSdk = 35 compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } defaultConfig { @@ -40,8 +40,6 @@ android { dependencies { testImplementation("junit:junit:4.13.2") testImplementation("org.mockito:mockito-core:5.0.0") - testImplementation ('org.robolectric:robolectric:4.12.2') - } testOptions { diff --git a/packages/instabug_flutter_ndk/android/gradle/wrapper/gradle-wrapper.properties b/packages/instabug_flutter_ndk/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..09523c0e5 --- /dev/null +++ b/packages/instabug_flutter_ndk/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/packages/instabug_flutter_ndk/android/gradlew b/packages/instabug_flutter_ndk/android/gradlew new file mode 100755 index 000000000..f5feea6d6 --- /dev/null +++ b/packages/instabug_flutter_ndk/android/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/packages/instabug_flutter_ndk/android/gradlew.bat b/packages/instabug_flutter_ndk/android/gradlew.bat new file mode 100644 index 000000000..9b42019c7 --- /dev/null +++ b/packages/instabug_flutter_ndk/android/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/packages/instabug_flutter_ndk/android/native.gradle b/packages/instabug_flutter_ndk/android/native.gradle new file mode 100644 index 000000000..38b6cd54c --- /dev/null +++ b/packages/instabug_flutter_ndk/android/native.gradle @@ -0,0 +1,7 @@ +project.ext.instabug = [ + version: '15.0.2' +] + +dependencies { + api "com.instabug.library:instabug-ndk-crash:${instabug.version}" +} \ No newline at end of file diff --git a/packages/instabug_flutter_ndk/android/settings.gradle b/packages/instabug_flutter_ndk/android/settings.gradle new file mode 100644 index 000000000..29158ad65 --- /dev/null +++ b/packages/instabug_flutter_ndk/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'instabug_flutter_ndk' diff --git a/packages/instabug_private_views/android/src/main/AndroidManifest.xml b/packages/instabug_flutter_ndk/android/src/main/AndroidManifest.xml similarity index 62% rename from packages/instabug_private_views/android/src/main/AndroidManifest.xml rename to packages/instabug_flutter_ndk/android/src/main/AndroidManifest.xml index 23fe3b997..326159d2c 100644 --- a/packages/instabug_private_views/android/src/main/AndroidManifest.xml +++ b/packages/instabug_flutter_ndk/android/src/main/AndroidManifest.xml @@ -1,3 +1,3 @@ + package="com.instabug.instabug_flutter_ndk"> diff --git a/packages/instabug_flutter_ndk/android/src/main/java/com/instabug/instabug_flutter_ndk/InstabugFlutterNdkPlugin.java b/packages/instabug_flutter_ndk/android/src/main/java/com/instabug/instabug_flutter_ndk/InstabugFlutterNdkPlugin.java new file mode 100644 index 000000000..0c507f02d --- /dev/null +++ b/packages/instabug_flutter_ndk/android/src/main/java/com/instabug/instabug_flutter_ndk/InstabugFlutterNdkPlugin.java @@ -0,0 +1,17 @@ +package com.instabug.instabug_flutter_ndk; + +import androidx.annotation.NonNull; +import io.flutter.embedding.engine.plugins.FlutterPlugin; + +/** InstabugFlutterNdkPlugin - Pure dependency plugin for NDK crash monitoring */ +public class InstabugFlutterNdkPlugin implements FlutterPlugin { + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { + // No method channel needed - this is a pure dependency plugin + } + + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + // Cleanup if needed + } +} diff --git a/packages/instabug_flutter_ndk/android/src/test/java/com/instabug/instabug_flutter_ndk/InstabugFlutterNdkPluginTest.java b/packages/instabug_flutter_ndk/android/src/test/java/com/instabug/instabug_flutter_ndk/InstabugFlutterNdkPluginTest.java new file mode 100644 index 000000000..86e65cc0d --- /dev/null +++ b/packages/instabug_flutter_ndk/android/src/test/java/com/instabug/instabug_flutter_ndk/InstabugFlutterNdkPluginTest.java @@ -0,0 +1,29 @@ +package com.instabug.instabug_flutter_ndk; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import org.junit.Test; + +/** + * This demonstrates a simple unit test of the Java portion of this plugin's implementation. + * + * Once you have built the plugin's example app, you can run these tests from the command + * line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or + * you can run them directly from IDEs that support JUnit such as Android Studio. + */ + +public class InstabugFlutterNdkPluginTest { + @Test + public void onMethodCall_getPlatformVersion_returnsExpectedValue() { + InstabugFlutterNdkPlugin plugin = new InstabugFlutterNdkPlugin(); + + final MethodCall call = new MethodCall("getPlatformVersion", null); + MethodChannel.Result mockResult = mock(MethodChannel.Result.class); + plugin.onMethodCall(call, mockResult); + + verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE); + } +} diff --git a/packages/instabug_flutter_ndk/example/.gitignore b/packages/instabug_flutter_ndk/example/.gitignore new file mode 100644 index 000000000..79c113f9b --- /dev/null +++ b/packages/instabug_flutter_ndk/example/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# 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 +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/instabug_private_views/example/README.md b/packages/instabug_flutter_ndk/example/README.md similarity index 84% rename from packages/instabug_private_views/example/README.md rename to packages/instabug_flutter_ndk/example/README.md index 81240d7ca..b93e44d8d 100644 --- a/packages/instabug_private_views/example/README.md +++ b/packages/instabug_flutter_ndk/example/README.md @@ -1,6 +1,6 @@ -# instabug_private_views_example +# instabug_flutter_ndk_example -Demonstrates how to use the instabug_private_views plugin. +Demonstrates how to use the instabug_flutter_ndk plugin. ## Getting Started diff --git a/packages/instabug_flutter_ndk/example/analysis_options.yaml b/packages/instabug_flutter_ndk/example/analysis_options.yaml new file mode 100644 index 000000000..0d2902135 --- /dev/null +++ b/packages/instabug_flutter_ndk/example/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/instabug_flutter_ndk/example/android/.gitignore b/packages/instabug_flutter_ndk/example/android/.gitignore new file mode 100644 index 000000000..be3943c96 --- /dev/null +++ b/packages/instabug_flutter_ndk/example/android/.gitignore @@ -0,0 +1,14 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java +.cxx/ + +# Remember to never publicly share your keystore. +# See https://flutter.dev/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/packages/instabug_private_views/example/android/app/build.gradle b/packages/instabug_flutter_ndk/example/android/app/build.gradle.kts similarity index 65% rename from packages/instabug_private_views/example/android/app/build.gradle rename to packages/instabug_flutter_ndk/example/android/app/build.gradle.kts index a3103874a..a52643fc4 100644 --- a/packages/instabug_private_views/example/android/app/build.gradle +++ b/packages/instabug_flutter_ndk/example/android/app/build.gradle.kts @@ -1,27 +1,27 @@ plugins { - id "com.android.application" - id "kotlin-android" + id("com.android.application") + id("kotlin-android") // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. - id "dev.flutter.flutter-gradle-plugin" + id("dev.flutter.flutter-gradle-plugin") } android { - namespace = "com.instabug.instabug_private_views_example" - compileSdk = 34 + namespace = "com.instabug.instabug_flutter_ndk_example" + compileSdk = flutter.compileSdkVersion ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8 + jvmTarget = JavaVersion.VERSION_11.toString() } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId = "com.instabug.instabug_private_views_example" + applicationId = "com.instabug.instabug_flutter_ndk_example" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. minSdk = flutter.minSdkVersion @@ -34,7 +34,7 @@ android { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.debug + signingConfig = signingConfigs.getByName("debug") } } } diff --git a/packages/instabug_private_views/example/android/app/src/debug/AndroidManifest.xml b/packages/instabug_flutter_ndk/example/android/app/src/debug/AndroidManifest.xml similarity index 100% rename from packages/instabug_private_views/example/android/app/src/debug/AndroidManifest.xml rename to packages/instabug_flutter_ndk/example/android/app/src/debug/AndroidManifest.xml diff --git a/packages/instabug_private_views/example/android/app/src/main/AndroidManifest.xml b/packages/instabug_flutter_ndk/example/android/app/src/main/AndroidManifest.xml similarity index 97% rename from packages/instabug_private_views/example/android/app/src/main/AndroidManifest.xml rename to packages/instabug_flutter_ndk/example/android/app/src/main/AndroidManifest.xml index 1a4340728..367e03d81 100644 --- a/packages/instabug_private_views/example/android/app/src/main/AndroidManifest.xml +++ b/packages/instabug_flutter_ndk/example/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ ("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/packages/instabug_flutter_ndk/example/android/gradle.properties b/packages/instabug_flutter_ndk/example/android/gradle.properties new file mode 100644 index 000000000..f018a6181 --- /dev/null +++ b/packages/instabug_flutter_ndk/example/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/instabug_private_views/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/instabug_flutter_ndk/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 91% rename from packages/instabug_private_views/example/android/gradle/wrapper/gradle-wrapper.properties rename to packages/instabug_flutter_ndk/example/android/gradle/wrapper/gradle-wrapper.properties index 7bb2df6ba..afa1e8eb0 100644 --- a/packages/instabug_private_views/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/instabug_flutter_ndk/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip diff --git a/packages/instabug_flutter_ndk/example/android/settings.gradle.kts b/packages/instabug_flutter_ndk/example/android/settings.gradle.kts new file mode 100644 index 000000000..a439442c2 --- /dev/null +++ b/packages/instabug_flutter_ndk/example/android/settings.gradle.kts @@ -0,0 +1,25 @@ +pluginManagement { + val flutterSdkPath = run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "8.7.0" apply false + id("org.jetbrains.kotlin.android") version "1.8.22" apply false +} + +include(":app") diff --git a/packages/instabug_flutter_ndk/example/integration_test/plugin_integration_test.dart b/packages/instabug_flutter_ndk/example/integration_test/plugin_integration_test.dart new file mode 100644 index 000000000..e9eb62c06 --- /dev/null +++ b/packages/instabug_flutter_ndk/example/integration_test/plugin_integration_test.dart @@ -0,0 +1,25 @@ +// This is a basic Flutter integration test. +// +// Since integration tests run in a full Flutter application, they can interact +// with the host side of a plugin implementation, unlike Dart unit tests. +// +// For more information about Flutter integration tests, please see +// https://flutter.dev/to/integration-testing + + +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'package:instabug_flutter_ndk/instabug_flutter_ndk.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('getPlatformVersion test', (WidgetTester tester) async { + final InstabugFlutterNdk plugin = InstabugFlutterNdk(); + final String? version = await plugin.getPlatformVersion(); + // The version string depends on the host platform running the test, so + // just assert that some non-empty string is returned. + expect(version?.isNotEmpty, true); + }); +} diff --git a/packages/instabug_flutter_ndk/example/ios/.gitignore b/packages/instabug_flutter_ndk/example/ios/.gitignore new file mode 100644 index 000000000..7a7f9873a --- /dev/null +++ b/packages/instabug_flutter_ndk/example/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/packages/instabug_private_views/example/ios/Flutter/AppFrameworkInfo.plist b/packages/instabug_flutter_ndk/example/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from packages/instabug_private_views/example/ios/Flutter/AppFrameworkInfo.plist rename to packages/instabug_flutter_ndk/example/ios/Flutter/AppFrameworkInfo.plist diff --git a/packages/instabug_flutter_ndk/example/ios/Flutter/Debug.xcconfig b/packages/instabug_flutter_ndk/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000..592ceee85 --- /dev/null +++ b/packages/instabug_flutter_ndk/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/packages/instabug_flutter_ndk/example/ios/Flutter/Release.xcconfig b/packages/instabug_flutter_ndk/example/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000..592ceee85 --- /dev/null +++ b/packages/instabug_flutter_ndk/example/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/packages/instabug_private_views/example/ios/Runner.xcodeproj/project.pbxproj b/packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/project.pbxproj similarity index 70% rename from packages/instabug_private_views/example/ios/Runner.xcodeproj/project.pbxproj rename to packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/project.pbxproj index ef3f7beed..1e5ded756 100644 --- a/packages/instabug_private_views/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/project.pbxproj @@ -8,15 +8,12 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 4EA625EC1B1293615B30A623 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92C8C175664DB55D5FE2AE9D /* Pods_RunnerTests.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 8115939F17BE56A387B25531 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15AA449B734113B9F4617C0E /* Pods_Runner.framework */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - BE133A632CD831A500FEADB5 /* PrivateViewHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BE133A622CD831A500FEADB5 /* PrivateViewHostApiTests.m */; }; - BE9F8D392CD5C068003ADA97 /* PrivateViewApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D382CD5C068003ADA97 /* PrivateViewApiTests.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -43,19 +40,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 0303582970644CA58D276892 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 15AA449B734113B9F4617C0E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3F54E317D7EFCD6FA9EBC039 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 820D7973B5497175631FF34A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 8801EEBF9F9D8EE99D4ED5A2 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; - 92C8C175664DB55D5FE2AE9D /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -63,11 +55,6 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 99B4BB79D25D93036AAF6480 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - A1871ACDFF6D3EA7210660EF /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - BE133A622CD831A500FEADB5 /* PrivateViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrivateViewHostApiTests.m; sourceTree = ""; }; - BE9F8D382CD5C068003ADA97 /* PrivateViewApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrivateViewApiTests.m; sourceTree = ""; }; - BE9F8D3A2CD5C06A003ADA97 /* RunnerTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RunnerTests-Bridging-Header.h"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -75,15 +62,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8115939F17BE56A387B25531 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C7F1472ADA1CCAD68225BF65 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4EA625EC1B1293615B30A623 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -93,35 +71,11 @@ 331C8082294A63A400263BE5 /* RunnerTests */ = { isa = PBXGroup; children = ( - BE9F8D382CD5C068003ADA97 /* PrivateViewApiTests.m */, - BE9F8D3A2CD5C06A003ADA97 /* RunnerTests-Bridging-Header.h */, - BE133A622CD831A500FEADB5 /* PrivateViewHostApiTests.m */, + 331C807B294A618700263BE5 /* RunnerTests.swift */, ); path = RunnerTests; sourceTree = ""; }; - 51A32382AC0867EEF3CF4501 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 15AA449B734113B9F4617C0E /* Pods_Runner.framework */, - 92C8C175664DB55D5FE2AE9D /* Pods_RunnerTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 940EE8988085F83C8461DB17 /* Pods */ = { - isa = PBXGroup; - children = ( - 820D7973B5497175631FF34A /* Pods-Runner.debug.xcconfig */, - 99B4BB79D25D93036AAF6480 /* Pods-Runner.release.xcconfig */, - 0303582970644CA58D276892 /* Pods-Runner.profile.xcconfig */, - 8801EEBF9F9D8EE99D4ED5A2 /* Pods-RunnerTests.debug.xcconfig */, - A1871ACDFF6D3EA7210660EF /* Pods-RunnerTests.release.xcconfig */, - 3F54E317D7EFCD6FA9EBC039 /* Pods-RunnerTests.profile.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -140,8 +94,6 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, - 940EE8988085F83C8461DB17 /* Pods */, - 51A32382AC0867EEF3CF4501 /* Frameworks */, ); sourceTree = ""; }; @@ -176,11 +128,8 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( - 5D0C51123159955CBB75DD3C /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, - C7F1472ADA1CCAD68225BF65 /* Frameworks */, - 40EB49289482643018B2EF40 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -196,14 +145,12 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - FA0379807AF94B93BE4FA182 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 589206114E198C940A065FDE /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -226,7 +173,6 @@ TargetAttributes = { 331C8080294A63A400263BE5 = { CreatedOnToolsVersion = 14.0; - LastSwiftMigration = 1600; TestTargetID = 97C146ED1CF9000F007C117D; }; 97C146ED1CF9000F007C117D = { @@ -292,62 +238,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 40EB49289482643018B2EF40 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RunnerTests/Pods-RunnerTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 589206114E198C940A065FDE /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 5D0C51123159955CBB75DD3C /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -363,28 +253,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - FA0379807AF94B93BE4FA182 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -392,8 +260,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BE9F8D392CD5C068003ADA97 /* PrivateViewApiTests.m in Sources */, - BE133A632CD831A500FEADB5 /* PrivateViewHostApiTests.m in Sources */, + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -495,14 +362,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 4574PQBJA9; + DEVELOPMENT_TEAM = MRHH8MT9X9; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.instabug.example; + PRODUCT_BUNDLE_IDENTIFIER = com.instabug.instabugFlutterNdkExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -512,18 +379,15 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8801EEBF9F9D8EE99D4ED5A2 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.instabug.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.instabug.instabugFlutterNdkExample.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -532,17 +396,14 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A1871ACDFF6D3EA7210660EF /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.instabug.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.instabug.instabugFlutterNdkExample.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; }; @@ -550,17 +411,14 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3F54E317D7EFCD6FA9EBC039 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.instabug.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.instabug.instabugFlutterNdkExample.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "RunnerTests/RunnerTests-Bridging-Header.h"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; }; @@ -684,14 +542,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 4574PQBJA9; + DEVELOPMENT_TEAM = MRHH8MT9X9; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.instabug.example; + PRODUCT_BUNDLE_IDENTIFIER = com.instabug.instabugFlutterNdkExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -707,14 +565,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 4574PQBJA9; + DEVELOPMENT_TEAM = MRHH8MT9X9; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.instabug.example; + PRODUCT_BUNDLE_IDENTIFIER = com.instabug.instabugFlutterNdkExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/packages/instabug_private_views/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from packages/instabug_private_views/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/packages/instabug_private_views/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from packages/instabug_private_views/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/packages/instabug_private_views/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings similarity index 100% rename from packages/instabug_private_views/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings rename to packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/packages/instabug_private_views/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 99% rename from packages/instabug_private_views/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 8e3ca5dfe..15cada483 100644 --- a/packages/instabug_private_views/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/instabug_flutter_ndk/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -59,6 +59,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/packages/instabug_private_views/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/instabug_flutter_ndk/example/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 67% rename from packages/instabug_private_views/example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to packages/instabug_flutter_ndk/example/ios/Runner.xcworkspace/contents.xcworkspacedata index 21a3cc14c..1d526a16e 100644 --- a/packages/instabug_private_views/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/packages/instabug_flutter_ndk/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,7 +4,4 @@ - - diff --git a/packages/instabug_private_views/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/instabug_flutter_ndk/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from packages/instabug_private_views/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to packages/instabug_flutter_ndk/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/packages/instabug_private_views/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/instabug_flutter_ndk/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings similarity index 100% rename from packages/instabug_private_views/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings rename to packages/instabug_flutter_ndk/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/packages/instabug_private_views/example/ios/Runner/AppDelegate.swift b/packages/instabug_flutter_ndk/example/ios/Runner/AppDelegate.swift similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/AppDelegate.swift rename to packages/instabug_flutter_ndk/example/ios/Runner/AppDelegate.swift diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png diff --git a/packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md rename to packages/instabug_flutter_ndk/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md diff --git a/packages/instabug_private_views/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/instabug_flutter_ndk/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to packages/instabug_flutter_ndk/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/packages/instabug_private_views/example/ios/Runner/Base.lproj/Main.storyboard b/packages/instabug_flutter_ndk/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Base.lproj/Main.storyboard rename to packages/instabug_flutter_ndk/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/packages/instabug_private_views/example/ios/Runner/Info.plist b/packages/instabug_flutter_ndk/example/ios/Runner/Info.plist similarity index 94% rename from packages/instabug_private_views/example/ios/Runner/Info.plist rename to packages/instabug_flutter_ndk/example/ios/Runner/Info.plist index 5458fc418..bbdc8a9f7 100644 --- a/packages/instabug_private_views/example/ios/Runner/Info.plist +++ b/packages/instabug_flutter_ndk/example/ios/Runner/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Example + Instabug Flutter Ndk CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - example + instabug_flutter_ndk_example CFBundlePackageType APPL CFBundleShortVersionString diff --git a/packages/instabug_private_views/example/ios/Runner/Runner-Bridging-Header.h b/packages/instabug_flutter_ndk/example/ios/Runner/Runner-Bridging-Header.h similarity index 100% rename from packages/instabug_private_views/example/ios/Runner/Runner-Bridging-Header.h rename to packages/instabug_flutter_ndk/example/ios/Runner/Runner-Bridging-Header.h diff --git a/packages/instabug_flutter_ndk/example/ios/RunnerTests/RunnerTests.swift b/packages/instabug_flutter_ndk/example/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 000000000..daf90c7b3 --- /dev/null +++ b/packages/instabug_flutter_ndk/example/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,27 @@ +import Flutter +import UIKit +import XCTest + + +@testable import instabug_flutter_ndk + +// This demonstrates a simple unit test of the Swift portion of this plugin's implementation. +// +// See https://developer.apple.com/documentation/xctest for more information about using XCTest. + +class RunnerTests: XCTestCase { + + func testGetPlatformVersion() { + let plugin = InstabugFlutterNdkPlugin() + + let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: []) + + let resultExpectation = expectation(description: "result block must be called.") + plugin.handle(call) { result in + XCTAssertEqual(result as! String, "iOS " + UIDevice.current.systemVersion) + resultExpectation.fulfill() + } + waitForExpectations(timeout: 1) + } + +} diff --git a/packages/instabug_flutter_ndk/example/lib/main.dart b/packages/instabug_flutter_ndk/example/lib/main.dart new file mode 100644 index 000000000..38b2575bf --- /dev/null +++ b/packages/instabug_flutter_ndk/example/lib/main.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:instabug_flutter_ndk/instabug_flutter_ndk.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatefulWidget { + const MyApp({super.key}); + + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + String _platformVersion = 'Unknown'; + final _instabugFlutterNdkPlugin = InstabugFlutterNdk(); + + @override + void initState() { + super.initState(); + initPlatformState(); + } + + // Platform messages are asynchronous, so we initialize in an async method. + Future initPlatformState() async { + String platformVersion; + // Platform messages may fail, so we use a try/catch PlatformException. + // We also handle the message potentially returning null. + try { + platformVersion = + await _instabugFlutterNdkPlugin.getPlatformVersion() ?? 'Unknown platform version'; + } on PlatformException { + platformVersion = 'Failed to get platform version.'; + } + + // If the widget was removed from the tree while the asynchronous platform + // message was in flight, we want to discard the reply rather than calling + // setState to update our non-existent appearance. + if (!mounted) return; + + setState(() { + _platformVersion = platformVersion; + }); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: Center( + child: Text('Running on: $_platformVersion\n'), + ), + ), + ); + } +} diff --git a/packages/instabug_private_views/example/pubspec.lock b/packages/instabug_flutter_ndk/example/pubspec.lock similarity index 57% rename from packages/instabug_private_views/example/pubspec.lock rename to packages/instabug_flutter_ndk/example/pubspec.lock index 5e8a12aa4..0fdcf9fdf 100644 --- a/packages/instabug_private_views/example/pubspec.lock +++ b/packages/instabug_flutter_ndk/example/pubspec.lock @@ -5,50 +5,42 @@ packages: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" characters: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" - source: hosted - version: "1.18.0" - csslib: - dependency: transitive - description: - name: csslib - sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.19.1" cupertino_icons: dependency: "direct main" description: @@ -61,71 +53,74 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_driver: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "5.0.0" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" - flutter_web_plugins: + fuchsia_remote_debug_protocol: dependency: transitive description: flutter source: sdk version: "0.0.0" - html: - dependency: transitive - description: - name: html - sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" - url: "https://pub.dev" - source: hosted - version: "0.15.5" - instabug_flutter: - dependency: "direct overridden" - description: - path: "../../instabug_flutter" - relative: true - source: path - version: "14.0.0" - instabug_private_views: + instabug_flutter_ndk: dependency: "direct main" description: path: ".." relative: true source: path - version: "1.0.1" + version: "0.0.1" + integration_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.8" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: @@ -138,18 +133,18 @@ packages: dependency: transitive description: name: lints - sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "5.1.1" matcher: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -162,18 +157,26 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" path: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -182,59 +185,75 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + process: + dependency: transitive + description: + name: process + sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" + url: "https://pub.dev" + source: hosted + version: "5.0.3" sky_engine: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.1" + sync_http: + dependency: transitive + description: + name: sync_http + sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" + url: "https://pub.dev" + source: hosted + version: "0.3.1" term_glyph: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.4" vector_math: dependency: transitive description: @@ -243,62 +262,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - video_player: - dependency: "direct main" - description: - name: video_player - sha256: "4a8c3492d734f7c39c2588a3206707a05ee80cef52e8c7f3b2078d430c84bc17" - url: "https://pub.dev" - source: hosted - version: "2.9.2" - video_player_android: - dependency: transitive - description: - name: video_player_android - sha256: "391e092ba4abe2f93b3e625bd6b6a6ec7d7414279462c1c0ee42b5ab8d0a0898" - url: "https://pub.dev" - source: hosted - version: "2.7.16" - video_player_avfoundation: - dependency: transitive - description: - name: video_player_avfoundation - sha256: "0b146e5d82e886ff43e5a46c6bcbe390761b802864a6e2503eb612d69a405dfa" - url: "https://pub.dev" - source: hosted - version: "2.6.3" - video_player_platform_interface: - dependency: transitive - description: - name: video_player_platform_interface - sha256: "229d7642ccd9f3dc4aba169609dd6b5f3f443bb4cc15b82f7785fcada5af9bbb" - url: "https://pub.dev" - source: hosted - version: "6.2.3" - video_player_web: - dependency: transitive - description: - name: video_player_web - sha256: "881b375a934d8ebf868c7fb1423b2bfaa393a0a265fa3f733079a86536064a10" - url: "https://pub.dev" - source: hosted - version: "2.3.3" vm_service: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" url: "https://pub.dev" source: hosted - version: "14.2.5" - web: + version: "14.3.1" + webdriver: dependency: transitive description: - name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + name: webdriver + sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "3.0.4" sdks: - dart: ">=3.5.0 <4.0.0" - flutter: ">=3.24.0" + dart: ">=3.7.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/packages/instabug_private_views/example/pubspec.yaml b/packages/instabug_flutter_ndk/example/pubspec.yaml similarity index 59% rename from packages/instabug_private_views/example/pubspec.yaml rename to packages/instabug_flutter_ndk/example/pubspec.yaml index 8e9d153ee..6b23a576d 100644 --- a/packages/instabug_private_views/example/pubspec.yaml +++ b/packages/instabug_flutter_ndk/example/pubspec.yaml @@ -1,21 +1,37 @@ -name: instabug_private_views_example -description: "Demonstrates how to use the instabug_private_views plugin." +name: instabug_flutter_ndk_example +description: "Demonstrates how to use the instabug_flutter_ndk plugin." +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: ">=2.12.0 <4.0.0" + sdk: ^3.7.0 +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter - instabug_private_views: - path: '../' + instabug_flutter_ndk: + # When depending on this package from a real application you should use: + # instabug_flutter_ndk: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 - video_player: dev_dependencies: + integration_test: + sdk: flutter flutter_test: sdk: flutter @@ -24,7 +40,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^4.0.0 + flutter_lints: ^5.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -38,8 +54,9 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - assets: - - assets/img.png + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images diff --git a/packages/instabug_flutter_ndk/example/test/widget_test.dart b/packages/instabug_flutter_ndk/example/test/widget_test.dart new file mode 100644 index 000000000..a492377d7 --- /dev/null +++ b/packages/instabug_flutter_ndk/example/test/widget_test.dart @@ -0,0 +1,27 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. 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:instabug_flutter_ndk_example/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Text && + widget.data!.startsWith('Running on:'), + ), + findsOneWidget, + ); + }); +} diff --git a/packages/instabug_private_views/ios/.gitignore b/packages/instabug_flutter_ndk/ios/.gitignore similarity index 100% rename from packages/instabug_private_views/ios/.gitignore rename to packages/instabug_flutter_ndk/ios/.gitignore diff --git a/packages/instabug_private_views/ios/Assets/.gitkeep b/packages/instabug_flutter_ndk/ios/Assets/.gitkeep similarity index 100% rename from packages/instabug_private_views/ios/Assets/.gitkeep rename to packages/instabug_flutter_ndk/ios/Assets/.gitkeep diff --git a/packages/instabug_flutter_ndk/ios/Classes/InstabugFlutterNdkPlugin.swift b/packages/instabug_flutter_ndk/ios/Classes/InstabugFlutterNdkPlugin.swift new file mode 100644 index 000000000..90041c978 --- /dev/null +++ b/packages/instabug_flutter_ndk/ios/Classes/InstabugFlutterNdkPlugin.swift @@ -0,0 +1,19 @@ +import Flutter +import UIKit + +public class InstabugFlutterNdkPlugin: NSObject, FlutterPlugin { + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "instabug_flutter_ndk", binaryMessenger: registrar.messenger()) + let instance = InstabugFlutterNdkPlugin() + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "getPlatformVersion": + result("iOS " + UIDevice.current.systemVersion) + default: + result(FlutterMethodNotImplemented) + } + } +} diff --git a/packages/instabug_private_views/ios/Resources/PrivacyInfo.xcprivacy b/packages/instabug_flutter_ndk/ios/Resources/PrivacyInfo.xcprivacy similarity index 100% rename from packages/instabug_private_views/ios/Resources/PrivacyInfo.xcprivacy rename to packages/instabug_flutter_ndk/ios/Resources/PrivacyInfo.xcprivacy diff --git a/packages/instabug_private_views/ios/instabug_private_views.podspec b/packages/instabug_flutter_ndk/ios/instabug_flutter_ndk.podspec similarity index 71% rename from packages/instabug_private_views/ios/instabug_private_views.podspec rename to packages/instabug_flutter_ndk/ios/instabug_flutter_ndk.podspec index 39751464c..7a78e9a5f 100644 --- a/packages/instabug_private_views/ios/instabug_private_views.podspec +++ b/packages/instabug_flutter_ndk/ios/instabug_flutter_ndk.podspec @@ -1,30 +1,29 @@ # # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint instabug_private_views.podspec` to validate before publishing. +# Run `pod lib lint instabug_flutter_ndk.podspec` to validate before publishing. # Pod::Spec.new do |s| - s.name = 'instabug_private_views' + s.name = 'instabug_flutter_ndk' s.version = '0.0.1' - s.summary = 'A new Flutter plugin project.' + s.summary = 'Instabug NDK Crash monitoring for Flutter' s.description = <<-DESC -A new Flutter plugin project. +Instabug NDK Crash monitoring for Flutter DESC s.homepage = 'http://example.com' s.license = { :file => '../LICENSE' } s.author = { 'Your Company' => 'email@example.com' } s.source = { :path => '.' } s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.dependency 'instabug_flutter' s.platform = :ios, '12.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } + s.swift_version = '5.0' # If your plugin requires a privacy manifest, for example if it uses any # required reason APIs, update the PrivacyInfo.xcprivacy file to describe your # plugin's privacy impact, and then uncomment this line. For more information, # see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files - # s.resource_bundles = {'instabug_private_views_privacy' => ['Resources/PrivacyInfo.xcprivacy']} + # s.resource_bundles = {'instabug_flutter_ndk_privacy' => ['Resources/PrivacyInfo.xcprivacy']} end diff --git a/packages/instabug_flutter_ndk/lib/instabug_flutter_ndk.dart b/packages/instabug_flutter_ndk/lib/instabug_flutter_ndk.dart new file mode 100644 index 000000000..8d21a12bc --- /dev/null +++ b/packages/instabug_flutter_ndk/lib/instabug_flutter_ndk.dart @@ -0,0 +1,5 @@ +// This package provides Instabug NDK crash monitoring for Flutter. +// It automatically includes the Android NDK dependency when added to a project. +// No public API is exposed - this is a pure dependency package. + +library instabug_flutter_ndk; diff --git a/packages/instabug_flutter_ndk/pubspec.yaml b/packages/instabug_flutter_ndk/pubspec.yaml new file mode 100644 index 000000000..9ec98c421 --- /dev/null +++ b/packages/instabug_flutter_ndk/pubspec.yaml @@ -0,0 +1,71 @@ +name: instabug_flutter_ndk +description: "Instabug NDK Crash monitoring for Flutter" +version: 0.0.1 +homepage: + +environment: + sdk: ^3.7.0 + flutter: '>=3.3.0' + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + # This section identifies this Flutter project as a plugin project. + # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) + # which should be registered in the plugin registry. This is required for + # using method channels. + # The Android 'package' specifies package in which the registered class is. + # This is required for using method channels on Android. + # The 'ffiPlugin' specifies that native code should be built and bundled. + # This is required for using `dart:ffi`. + # All these are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + platforms: + android: + package: com.instabug.instabug_flutter_ndk + pluginClass: InstabugFlutterNdkPlugin + ios: + pluginClass: InstabugFlutterNdkPlugin + + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/to/asset-from-package + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # To add custom fonts to your plugin package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/to/font-from-package diff --git a/packages/instabug_flutter_ndk/test/instabug_flutter_ndk_method_channel_test.dart b/packages/instabug_flutter_ndk/test/instabug_flutter_ndk_method_channel_test.dart new file mode 100644 index 000000000..61b5aeab6 --- /dev/null +++ b/packages/instabug_flutter_ndk/test/instabug_flutter_ndk_method_channel_test.dart @@ -0,0 +1,27 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:instabug_flutter_ndk/instabug_flutter_ndk_method_channel.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + MethodChannelInstabugFlutterNdk platform = MethodChannelInstabugFlutterNdk(); + const MethodChannel channel = MethodChannel('instabug_flutter_ndk'); + + setUp(() { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( + channel, + (MethodCall methodCall) async { + return '42'; + }, + ); + }); + + tearDown(() { + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(channel, null); + }); + + test('getPlatformVersion', () async { + expect(await platform.getPlatformVersion(), '42'); + }); +} diff --git a/packages/instabug_flutter_ndk/test/instabug_flutter_ndk_test.dart b/packages/instabug_flutter_ndk/test/instabug_flutter_ndk_test.dart new file mode 100644 index 000000000..a67395366 --- /dev/null +++ b/packages/instabug_flutter_ndk/test/instabug_flutter_ndk_test.dart @@ -0,0 +1,29 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:instabug_flutter_ndk/instabug_flutter_ndk.dart'; +import 'package:instabug_flutter_ndk/instabug_flutter_ndk_platform_interface.dart'; +import 'package:instabug_flutter_ndk/instabug_flutter_ndk_method_channel.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +class MockInstabugFlutterNdkPlatform + with MockPlatformInterfaceMixin + implements InstabugFlutterNdkPlatform { + + @override + Future getPlatformVersion() => Future.value('42'); +} + +void main() { + final InstabugFlutterNdkPlatform initialPlatform = InstabugFlutterNdkPlatform.instance; + + test('$MethodChannelInstabugFlutterNdk is the default instance', () { + expect(initialPlatform, isInstanceOf()); + }); + + test('getPlatformVersion', () async { + InstabugFlutterNdk instabugFlutterNdkPlugin = InstabugFlutterNdk(); + MockInstabugFlutterNdkPlatform fakePlatform = MockInstabugFlutterNdkPlatform(); + InstabugFlutterNdkPlatform.instance = fakePlatform; + + expect(await instabugFlutterNdkPlugin.getPlatformVersion(), '42'); + }); +} diff --git a/packages/instabug_http_client/example/pubspec.lock b/packages/instabug_http_client/example/pubspec.lock index 78cb15f97..c0867996d 100644 --- a/packages/instabug_http_client/example/pubspec.lock +++ b/packages/instabug_http_client/example/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" cupertino_icons: dependency: "direct main" description: @@ -109,18 +109,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -173,7 +173,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -186,10 +186,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -202,10 +202,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" term_glyph: dependency: transitive description: @@ -218,10 +218,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" typed_data: dependency: transitive description: @@ -242,10 +242,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" sdks: dart: ">=3.5.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/packages/instabug_http_client/example/pubspec_overrides.yaml b/packages/instabug_http_client/example/pubspec_overrides.yaml new file mode 100644 index 000000000..3daf4fd14 --- /dev/null +++ b/packages/instabug_http_client/example/pubspec_overrides.yaml @@ -0,0 +1,6 @@ +# melos_managed_dependency_overrides: instabug_flutter,instabug_http_client +dependency_overrides: + instabug_flutter: + path: ../../instabug_flutter + instabug_http_client: + path: .. diff --git a/packages/instabug_http_client/lib/instabug_http_client.dart b/packages/instabug_http_client/lib/instabug_http_client.dart index 624d72cc1..f32ed5f60 100644 --- a/packages/instabug_http_client/lib/instabug_http_client.dart +++ b/packages/instabug_http_client/lib/instabug_http_client.dart @@ -47,7 +47,9 @@ class InstabugHttpClient extends InstabugHttpLogger implements http.Client { } Future getW3cHeader( - Map requestHeader, DateTime startTime) async { + Map requestHeader, + DateTime startTime, + ) async { final w3cHeader = await _networklogger.getW3CHeader( requestHeader, startTime.millisecondsSinceEpoch, @@ -156,8 +158,11 @@ class InstabugHttpClient extends InstabugHttpLogger implements http.Client { (http.StreamedResponse streamedResponse) => http.Response.fromStream(streamedResponse) .then((http.Response response) { - logger.onLogger(response, - startTime: startTime, w3CHeader: w3cHeader); + logger.onLogger( + response, + startTime: startTime, + w3CHeader: w3cHeader, + ); // Need to return new StreamedResponse, as body only can be listened once return http.StreamedResponse( Stream>.value(response.bodyBytes), diff --git a/packages/instabug_http_client/lib/instabug_http_logger.dart b/packages/instabug_http_client/lib/instabug_http_logger.dart index a0b9fa6e7..fc97a831a 100644 --- a/packages/instabug_http_client/lib/instabug_http_logger.dart +++ b/packages/instabug_http_client/lib/instabug_http_logger.dart @@ -4,8 +4,11 @@ import 'package:http/http.dart' as http; import 'package:instabug_flutter/instabug_flutter.dart'; class InstabugHttpLogger { - void onLogger(http.Response response, - {DateTime? startTime, W3CHeader? w3CHeader}) { + void onLogger( + http.Response response, { + DateTime? startTime, + W3CHeader? w3CHeader, + }) { final networkLogger = NetworkLogger(); final requestHeaders = {}; diff --git a/packages/instabug_http_client/pubspec.lock b/packages/instabug_http_client/pubspec.lock index 576d3ee35..15fac02e7 100644 --- a/packages/instabug_http_client/pubspec.lock +++ b/packages/instabug_http_client/pubspec.lock @@ -5,23 +5,23 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 + sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" url: "https://pub.dev" source: hosted - version: "72.0.0" + version: "76.0.0" _macros: dependency: transitive description: dart source: sdk - version: "0.3.2" + version: "0.3.3" analyzer: dependency: transitive description: name: analyzer - sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 + sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" url: "https://pub.dev" source: hosted - version: "6.7.0" + version: "6.11.0" args: dependency: transitive description: @@ -154,10 +154,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" convert: dependency: transitive description: @@ -323,18 +323,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: @@ -363,10 +363,10 @@ packages: dependency: transitive description: name: macros - sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" url: "https://pub.dev" source: hosted - version: "0.1.2-main.4" + version: "0.1.3-main.0" markdown: dependency: transitive description: @@ -523,7 +523,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_gen: dependency: transitive description: @@ -560,10 +560,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -584,10 +584,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" tar: dependency: transitive description: @@ -608,26 +608,26 @@ packages: dependency: transitive description: name: test - sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" + sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f" url: "https://pub.dev" source: hosted - version: "1.25.7" + version: "1.25.8" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.3" test_core: dependency: transitive description: name: test_core - sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" + sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d" url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" timing: dependency: transitive description: @@ -656,10 +656,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.3.0" watcher: dependency: transitive description: diff --git a/packages/instabug_http_client/test/instabug_http_client_test.dart b/packages/instabug_http_client/test/instabug_http_client_test.dart index abcd12b25..73014020b 100644 --- a/packages/instabug_http_client/test/instabug_http_client_test.dart +++ b/packages/instabug_http_client/test/instabug_http_client_test.dart @@ -55,8 +55,8 @@ Future main() async { test('expect instabug http client GET to return response', () async { when( - instabugHttpClient.client.get(url, headers: anyNamed('headers'))) - .thenAnswer((_) async => mockedResponse); + instabugHttpClient.client.get(url, headers: anyNamed('headers')), + ).thenAnswer((_) async => mockedResponse); final result = await instabugHttpClient.get(url); expect(result, isInstanceOf()); expect(result, mockedResponse); @@ -68,8 +68,8 @@ Future main() async { test('expect instabug http client HEAD to return response', () async { when( - instabugHttpClient.client.head(url, headers: anyNamed('headers'))) - .thenAnswer((_) async => mockedResponse); + instabugHttpClient.client.head(url, headers: anyNamed('headers')), + ).thenAnswer((_) async => mockedResponse); final result = await instabugHttpClient.head(url); expect(result, isInstanceOf()); expect(result, mockedResponse); @@ -81,8 +81,8 @@ Future main() async { test('expect instabug http client DELETE to return response', () async { when( - instabugHttpClient.client.delete(url, headers: anyNamed('headers'))) - .thenAnswer((_) async => mockedResponse); + instabugHttpClient.client.delete(url, headers: anyNamed('headers')), + ).thenAnswer((_) async => mockedResponse); final result = await instabugHttpClient.delete(url); expect(result, isInstanceOf()); expect(result, mockedResponse); @@ -94,8 +94,8 @@ Future main() async { test('expect instabug http client PATCH to return response', () async { when( - instabugHttpClient.client.patch(url, headers: anyNamed('headers'))) - .thenAnswer((_) async => mockedResponse); + instabugHttpClient.client.patch(url, headers: anyNamed('headers')), + ).thenAnswer((_) async => mockedResponse); final result = await instabugHttpClient.patch(url); expect(result, isInstanceOf()); expect(result, mockedResponse); @@ -107,8 +107,8 @@ Future main() async { test('expect instabug http client POST to return response', () async { when( - instabugHttpClient.client.post(url, headers: anyNamed('headers'))) - .thenAnswer((_) async => mockedResponse); + instabugHttpClient.client.post(url, headers: anyNamed('headers')), + ).thenAnswer((_) async => mockedResponse); final result = await instabugHttpClient.post(url); expect(result, isInstanceOf()); expect(result, mockedResponse); @@ -120,8 +120,8 @@ Future main() async { test('expect instabug http client PUT to return response', () async { when( - instabugHttpClient.client.put(url, headers: anyNamed('headers'))) - .thenAnswer((_) async => mockedResponse); + instabugHttpClient.client.put(url, headers: anyNamed('headers')), + ).thenAnswer((_) async => mockedResponse); final result = await instabugHttpClient.put(url); expect(result, isInstanceOf()); expect(result.body, mockedResponse.body); @@ -134,8 +134,8 @@ Future main() async { test('expect instabug http client READ to return response', () async { const response = 'Some response string'; when( - instabugHttpClient.client.read(url, headers: anyNamed('headers'))) - .thenAnswer((_) async => response); + instabugHttpClient.client.read(url, headers: anyNamed('headers')), + ).thenAnswer((_) async => response); final result = await instabugHttpClient.read(url); expect(result, isInstanceOf()); @@ -194,8 +194,8 @@ Future main() async { test('stress test for GET method', () async { when( - instabugHttpClient.client.get(url, headers: anyNamed('headers'))) - .thenAnswer((_) async => mockedResponse); + instabugHttpClient.client.get(url, headers: anyNamed('headers')), + ).thenAnswer((_) async => mockedResponse); for (var i = 0; i < 10000; i++) { await instabugHttpClient.get(url); } diff --git a/packages/instabug_private_views/CHANGELOG.md b/packages/instabug_private_views/CHANGELOG.md deleted file mode 100644 index 26deb9dda..000000000 --- a/packages/instabug_private_views/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# Changelog - -## [UnReleased](https://github.com/Instabug/) - -### Added - -- Add support for masking private views during screen capturing ([#527](https://github.com/Instabug/Instabug-Flutter/pull/527)). diff --git a/packages/instabug_private_views/LICENSE b/packages/instabug_private_views/LICENSE deleted file mode 100644 index 80d729766..000000000 --- a/packages/instabug_private_views/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) Instabug - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/packages/instabug_private_views/README.md b/packages/instabug_private_views/README.md deleted file mode 100644 index 0c7f936a8..000000000 --- a/packages/instabug_private_views/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# instabug_private_views - -An add-on for the Instabug Flutter SDK that provides private views support in screen. - -[![Twitter](https://img.shields.io/badge/twitter-@Instabug-blue.svg)](https://twitter.com/Instabug) - -An add-on for the [Instabug Flutter SDK](https://github.com/Instabug/Instabug-Flutter) hat provides private views support in screenshot capturing [Flutter Private views](https://pub.dev/packages/). - -## Installation - -1. Add `instabug_private_views` to your `pubspec.yaml` file. - -```yaml -dependencies: - instabug_private_views: -``` - -2. Install the package by running the following command. - -```sh -flutter pub get -``` - -## Usage - -1. enable `PrivateViews` after `init` the SDK: - - -```dart - -void main() { - - Instabug.init( - token: 'App token', - invocationEvents: [InvocationEvent.floatingButton], - ); - - ReproSteps.enableMaskingPrivateViews(); - - runApp(MyApp()); - -} -``` - -2. Wrap the view you want to mask with `InstabugPrivateView`: - -```dart - InstabugPrivateView( -child: const Text( -'Private TextView', -style: TextStyle(fontSize: 18), -textAlign: TextAlign.center, -), -), -``` - -you can use `InstabugSliverPrivateView` if you want to wrap Sliver widget -```dart - InstabugSliverPrivateView( -sliver: SliverToBoxAdapter( -child: /// child -)), -``` \ No newline at end of file diff --git a/packages/instabug_private_views/android/settings.gradle b/packages/instabug_private_views/android/settings.gradle deleted file mode 100644 index 64f5453f5..000000000 --- a/packages/instabug_private_views/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'instabug_private_views' diff --git a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/InstabugPrivateViewsPlugin.java b/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/InstabugPrivateViewsPlugin.java deleted file mode 100644 index 2065b60c1..000000000 --- a/packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/InstabugPrivateViewsPlugin.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.instabug.instabug_private_views; - -import android.annotation.SuppressLint; -import android.app.Activity; - -import androidx.annotation.NonNull; - -import com.instabug.instabug_private_views.generated.InstabugPrivateViewPigeon; -import com.instabug.instabug_private_views.modules.capturing.BoundryCaptureManager; -import com.instabug.instabug_private_views.modules.InstabugPrivateView; -import com.instabug.instabug_private_views.modules.capturing.PixelCopyCaptureManager; -import com.instabug.instabug_private_views.modules.PrivateViewManager; -import com.instabug.library.internal.crossplatform.InternalCore; - -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.embedding.engine.plugins.activity.ActivityAware; -import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; -import io.flutter.embedding.engine.renderer.FlutterRenderer; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.PluginRegistry; - -/** - * InstabugPrivateViewsPlugin - */ -public class InstabugPrivateViewsPlugin implements FlutterPlugin, ActivityAware { - private static final String TAG = InstabugPrivateViewsPlugin.class.getName(); - - @SuppressLint("StaticFieldLeak") - private static Activity activity; - - PrivateViewManager privateViewManager; - - /** - * Embedding v1 - */ - @SuppressWarnings("deprecation") - public void registerWith(PluginRegistry.Registrar registrar) { - activity = registrar.activity(); - register( registrar.messenger(), (FlutterRenderer) registrar.textures()); - } - - - @Override - public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { - register(binding.getBinaryMessenger(), (FlutterRenderer) binding.getTextureRegistry()); - } - - @Override - public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { - activity = null; - } - - @Override - public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { - activity = binding.getActivity(); - if (privateViewManager != null) { - privateViewManager.setActivity(activity); - } - - } - - @Override - public void onDetachedFromActivityForConfigChanges() { - activity = null; - privateViewManager.setActivity(null); - - } - - @Override - public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { - activity = binding.getActivity(); - privateViewManager.setActivity(activity); - - } - - @Override - public void onDetachedFromActivity() { - activity = null; - privateViewManager.setActivity(null); - - } - - private void register(BinaryMessenger messenger, FlutterRenderer renderer) { - privateViewManager = new PrivateViewManager(new InstabugPrivateViewPigeon.InstabugPrivateViewFlutterApi(messenger), new PixelCopyCaptureManager(), new BoundryCaptureManager(renderer)); - InstabugPrivateView.init(messenger,privateViewManager); - - } -} diff --git a/packages/instabug_private_views/example-hybrid-ios-app/.gitignore b/packages/instabug_private_views/example-hybrid-ios-app/.gitignore deleted file mode 100644 index 2624e2177..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/.gitignore +++ /dev/null @@ -1,45 +0,0 @@ -# Xcode -DerivedData/ -build/ -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 -*.xcworkspace -!default.xcworkspace -xcuserdata/ -*.moved-aside -*.xcuserstate -*.xcscmblueprint - -# iOS Specific -*.hmap -*.ipa -*.dSYM.zip -*.dSYM - -# Swift Package Manager -.build/ -.swiftpm/xcode/package.xcworkspace/ -.swiftpm/ - -# CocoaPods (if used) -Pods/ -Podfile.lock - -# Carthage (if used) -Carthage/Build/ - -# Fastlane (if used) -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots -fastlane/test_output - -# Bundle artifact -*.xcarchive - -# Temporary files -*.tmp -*.swp -*.swm diff --git a/packages/instabug_private_views/example-hybrid-ios-app/Podfile b/packages/instabug_private_views/example-hybrid-ios-app/Podfile deleted file mode 100644 index 775126029..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/Podfile +++ /dev/null @@ -1,21 +0,0 @@ -# Uncomment the next line to define a global platform for your project -# platform :ios, '9.0' - -flutter_application_path = 'my_flutter' -load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') - -target 'hybrid-flutter-app' do - # Comment the next line if you don't want to use dynamic frameworks - pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/feature-flutter-private-views-base/13.4.2/Instabug.podspec' - - use_frameworks! - - install_all_flutter_pods(flutter_application_path) - - # Pods for hybrid-flutter-app - -end - -post_install do |installer| - flutter_post_install(installer) if defined?(flutter_post_install) -end diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app.xcodeproj/project.pbxproj b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app.xcodeproj/project.pbxproj deleted file mode 100644 index 5e6fb0c4d..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app.xcodeproj/project.pbxproj +++ /dev/null @@ -1,435 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 77; - objects = { - -/* Begin PBXBuildFile section */ - CC1152E765F8580640185243 /* Pods_hybrid_flutter_app.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 74A87659FEAAB6DF26380477 /* Pods_hybrid_flutter_app.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 6A35F6E0DFACBBAB47D661EA /* Pods-hybrid-flutter-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-hybrid-flutter-app.debug.xcconfig"; path = "Target Support Files/Pods-hybrid-flutter-app/Pods-hybrid-flutter-app.debug.xcconfig"; sourceTree = ""; }; - 74A87659FEAAB6DF26380477 /* Pods_hybrid_flutter_app.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_hybrid_flutter_app.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 9F7459A16324C6347AA6DAFB /* Pods-hybrid-flutter-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-hybrid-flutter-app.release.xcconfig"; path = "Target Support Files/Pods-hybrid-flutter-app/Pods-hybrid-flutter-app.release.xcconfig"; sourceTree = ""; }; - BE9EC8252CD1812F0026F537 /* hybrid-flutter-app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hybrid-flutter-app.app"; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ - BE9EC8372CD181310026F537 /* Exceptions for "hybrid-flutter-app" folder in "hybrid-flutter-app" target */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - Info.plist, - ); - target = BE9EC8242CD1812F0026F537 /* hybrid-flutter-app */; - }; -/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ - -/* Begin PBXFileSystemSynchronizedRootGroup section */ - BE9EC8272CD1812F0026F537 /* hybrid-flutter-app */ = { - isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - BE9EC8372CD181310026F537 /* Exceptions for "hybrid-flutter-app" folder in "hybrid-flutter-app" target */, - ); - path = "hybrid-flutter-app"; - sourceTree = ""; - }; -/* End PBXFileSystemSynchronizedRootGroup section */ - -/* Begin PBXFrameworksBuildPhase section */ - BE9EC8222CD1812F0026F537 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - CC1152E765F8580640185243 /* Pods_hybrid_flutter_app.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 324CF1E79ACC6661E48AC83B /* Pods */ = { - isa = PBXGroup; - children = ( - 6A35F6E0DFACBBAB47D661EA /* Pods-hybrid-flutter-app.debug.xcconfig */, - 9F7459A16324C6347AA6DAFB /* Pods-hybrid-flutter-app.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; - 60FD6C74BF2A20B8B71EECA2 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 74A87659FEAAB6DF26380477 /* Pods_hybrid_flutter_app.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - BE9EC81C2CD1812F0026F537 = { - isa = PBXGroup; - children = ( - BE9EC8272CD1812F0026F537 /* hybrid-flutter-app */, - BE9EC8262CD1812F0026F537 /* Products */, - 324CF1E79ACC6661E48AC83B /* Pods */, - 60FD6C74BF2A20B8B71EECA2 /* Frameworks */, - ); - sourceTree = ""; - }; - BE9EC8262CD1812F0026F537 /* Products */ = { - isa = PBXGroup; - children = ( - BE9EC8252CD1812F0026F537 /* hybrid-flutter-app.app */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - BE9EC8242CD1812F0026F537 /* hybrid-flutter-app */ = { - isa = PBXNativeTarget; - buildConfigurationList = BE9EC8382CD181310026F537 /* Build configuration list for PBXNativeTarget "hybrid-flutter-app" */; - buildPhases = ( - 12C1309DE0C239420C1F847F /* [CP] Check Pods Manifest.lock */, - 742AC800B4072D761DDE7C14 /* [CP-User] Run Flutter Build my_flutter Script */, - BE9EC8212CD1812F0026F537 /* Sources */, - BE9EC8222CD1812F0026F537 /* Frameworks */, - BE9EC8232CD1812F0026F537 /* Resources */, - 56BEAC412A6C93A663ED05C8 /* [CP-User] Embed Flutter Build my_flutter Script */, - A3E7F43B3A5E735EC880C3EF /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - fileSystemSynchronizedGroups = ( - BE9EC8272CD1812F0026F537 /* hybrid-flutter-app */, - ); - name = "hybrid-flutter-app"; - productName = "hybrid-flutter-app"; - productReference = BE9EC8252CD1812F0026F537 /* hybrid-flutter-app.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - BE9EC81D2CD1812F0026F537 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1600; - LastUpgradeCheck = 1600; - TargetAttributes = { - BE9EC8242CD1812F0026F537 = { - CreatedOnToolsVersion = 16.0; - }; - }; - }; - buildConfigurationList = BE9EC8202CD1812F0026F537 /* Build configuration list for PBXProject "hybrid-flutter-app" */; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = BE9EC81C2CD1812F0026F537; - minimizedProjectReferenceProxies = 1; - preferredProjectObjectVersion = 77; - productRefGroup = BE9EC8262CD1812F0026F537 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - BE9EC8242CD1812F0026F537 /* hybrid-flutter-app */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - BE9EC8232CD1812F0026F537 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 12C1309DE0C239420C1F847F /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-hybrid-flutter-app-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 56BEAC412A6C93A663ED05C8 /* [CP-User] Embed Flutter Build my_flutter Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - name = "[CP-User] Embed Flutter Build my_flutter Script"; - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "set -e\nset -u\nsource \"${SRCROOT}/my_flutter/.ios/Flutter/flutter_export_environment.sh\"\nexport VERBOSE_SCRIPT_LOGGING=1 && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh embed_and_thin"; - }; - 742AC800B4072D761DDE7C14 /* [CP-User] Run Flutter Build my_flutter Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - name = "[CP-User] Run Flutter Build my_flutter Script"; - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "set -e\nset -u\nsource \"${SRCROOT}/my_flutter/.ios/Flutter/flutter_export_environment.sh\"\nexport VERBOSE_SCRIPT_LOGGING=1 && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh build"; - }; - A3E7F43B3A5E735EC880C3EF /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-hybrid-flutter-app/Pods-hybrid-flutter-app-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-hybrid-flutter-app/Pods-hybrid-flutter-app-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-hybrid-flutter-app/Pods-hybrid-flutter-app-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - BE9EC8212CD1812F0026F537 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - BE9EC8392CD181310026F537 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 6A35F6E0DFACBBAB47D661EA /* Pods-hybrid-flutter-app.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = VF78H8LBT4; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = "hybrid-flutter-app/Info.plist"; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = "com.ahmedalaa.hybrid-flutter-app"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - BE9EC83A2CD181310026F537 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9F7459A16324C6347AA6DAFB /* Pods-hybrid-flutter-app.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = VF78H8LBT4; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = "hybrid-flutter-app/Info.plist"; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = "com.ahmedalaa.hybrid-flutter-app"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - BE9EC83B2CD181310026F537 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.0; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - BE9EC83C2CD181310026F537 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.0; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - BE9EC8202CD1812F0026F537 /* Build configuration list for PBXProject "hybrid-flutter-app" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BE9EC83B2CD181310026F537 /* Debug */, - BE9EC83C2CD181310026F537 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - BE9EC8382CD181310026F537 /* Build configuration list for PBXNativeTarget "hybrid-flutter-app" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BE9EC8392CD181310026F537 /* Debug */, - BE9EC83A2CD181310026F537 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = BE9EC81D2CD1812F0026F537 /* Project object */; -} diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/AppDelegate.swift b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/AppDelegate.swift deleted file mode 100644 index 9157e26ae..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/AppDelegate.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.swift -// hybrid-flutter-app -// -// Created by Ahmed alaa on 29/10/2024. -// - -import UIKit -import Flutter -import FlutterPluginRegistrant -@main -class AppDelegate: UIResponder, UIApplicationDelegate { - - var flutterEngine: FlutterEngine! - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - flutterEngine = FlutterEngine(name: "my flutter engine") - flutterEngine.run() - GeneratedPluginRegistrant.register(with: flutterEngine) - - return true - } - - // MARK: UISceneSession Lifecycle - - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) - } - - func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. - } - - -} - diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Assets.xcassets/AccentColor.colorset/Contents.json b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index eb8789700..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 230588010..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "tinted" - } - ], - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Assets.xcassets/Contents.json b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Base.lproj/LaunchScreen.storyboard b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 865e9329f..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Base.lproj/Main.storyboard b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Base.lproj/Main.storyboard deleted file mode 100644 index ddecb9df6..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Base.lproj/Main.storyboard +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Info.plist b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Info.plist deleted file mode 100644 index dd3c9afda..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/Info.plist +++ /dev/null @@ -1,25 +0,0 @@ - - - - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - UISceneConfigurations - - UIWindowSceneSessionRoleApplication - - - UISceneConfigurationName - Default Configuration - UISceneDelegateClassName - $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main - - - - - - diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/SceneDelegate.swift b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/SceneDelegate.swift deleted file mode 100644 index d41584377..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/SceneDelegate.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -// SceneDelegate.swift -// hybrid-flutter-app -// -// Created by Ahmed alaa on 29/10/2024. -// - -import UIKit - -class SceneDelegate: UIResponder, UIWindowSceneDelegate { - - var window: UIWindow? - - - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). - guard let _ = (scene as? UIWindowScene) else { return } - } - - func sceneDidDisconnect(_ scene: UIScene) { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). - } - - func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } - - func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). - } - - func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. - } - - func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. - } - - -} - diff --git a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/ViewController.swift b/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/ViewController.swift deleted file mode 100644 index 49fc98fd1..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/hybrid-flutter-app/ViewController.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// ViewController.swift -// hybrid-flutter-app -// -// Created by Ahmed alaa on 29/10/2024. -// - -import UIKit -import Flutter -class ViewController: UIViewController { - - @IBOutlet weak var flutterView: UIView! - override func viewDidLoad() { - super.viewDidLoad() - let appDelegate = UIApplication.shared.delegate as! AppDelegate - - - let flutterViewController = FlutterViewController(engine: appDelegate.flutterEngine, nibName: nil, bundle: nil) - - addChild(flutterViewController) - flutterViewController.view.frame = flutterView.bounds - flutterView.addSubview(flutterViewController.view) - flutterViewController.didMove(toParent: self) - // Do any additional setup after loading the view. - } - - -} - diff --git a/packages/instabug_private_views/example-hybrid-ios-app/init.sh b/packages/instabug_private_views/example-hybrid-ios-app/init.sh deleted file mode 100644 index bbdbd30db..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/init.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -cd my_flutter -flutter pub get -cd ../ -pod install --repo-update \ No newline at end of file diff --git a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/.gitignore b/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/.gitignore deleted file mode 100644 index 525e05cfb..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/.gitignore +++ /dev/null @@ -1,49 +0,0 @@ -.DS_Store -.dart_tool/ - -.pub/ - -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -migrate_working_dir/ - -*.swp -profile - -DerivedData/ - -.generated/ - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - -build/ -.android/ -.ios/ -.flutter-plugins -.flutter-plugins-dependencies - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json diff --git a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/.metadata b/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/.metadata deleted file mode 100644 index 1ff39d995..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/.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: "603104015dd692ea3403755b55d07813d5cf8965" - channel: "stable" - -project_type: module diff --git a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/README.md b/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/README.md deleted file mode 100644 index 12d679054..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# my_flutter - -A new Flutter module project. - -## Getting Started - -For help getting started with Flutter development, view the online -[documentation](https://flutter.dev/). - -For instructions integrating Flutter modules to your existing applications, -see the [add-to-app documentation](https://flutter.dev/to/add-to-app). diff --git a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/lib/main.dart b/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/lib/main.dart deleted file mode 100644 index 45f87f0bf..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/lib/main.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:instabug_flutter/instabug_flutter.dart'; -import 'package:instabug_private_views/instabug_private_view.dart'; - -void main() { - runZonedGuarded( - () { - WidgetsFlutterBinding.ensureInitialized(); - - Instabug.init( - token: 'ed6f659591566da19b67857e1b9d40ab', - invocationEvents: [InvocationEvent.floatingButton], - debugLogsLevel: LogLevel.verbose, - ); - - FlutterError.onError = (FlutterErrorDetails details) { - Zone.current.handleUncaughtError(details.exception, details.stack!); - }; - - enableInstabugMaskingPrivateViews(); - runApp(const MyApp()); - }, - CrashReporting.reportCrash, - ); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - debugShowCheckedModeBanner: false, - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: const MyHomePage(title: 'Flutter View'), - ); - } - - const MyApp({Key? key}) : super(key: key); -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({Key? key, required this.title}) : super(key: key); - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - InstabugPrivateView( - child: const Text( - 'Private text', - ), - ), - ], - ), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} diff --git a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/pubspec.lock b/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/pubspec.lock deleted file mode 100644 index 1e5288b3d..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/pubspec.lock +++ /dev/null @@ -1,227 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" - source: hosted - version: "1.18.0" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.dev" - source: hosted - version: "1.0.8" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" - url: "https://pub.dev" - source: hosted - version: "4.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - instabug_flutter: - dependency: "direct main" - description: - path: "../../../instabug_flutter" - relative: true - source: path - version: "14.0.0" - instabug_private_views: - dependency: "direct main" - description: - path: "../.." - relative: true - source: path - version: "1.0.1" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" - url: "https://pub.dev" - source: hosted - version: "10.0.5" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" - url: "https://pub.dev" - source: hosted - version: "3.0.5" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.dev" - source: hosted - version: "3.0.1" - lints: - dependency: transitive - description: - name: lints - sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" - url: "https://pub.dev" - source: hosted - version: "4.0.0" - matcher: - dependency: transitive - description: - name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" - source: hosted - version: "0.12.16+1" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" - source: hosted - version: "0.11.1" - meta: - dependency: transitive - description: - name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 - url: "https://pub.dev" - source: hosted - version: "1.15.0" - path: - dependency: transitive - description: - name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" - source: hosted - version: "1.9.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" - source: hosted - version: "1.10.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" - source: hosted - version: "1.11.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" - source: hosted - version: "2.1.2" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" - url: "https://pub.dev" - source: hosted - version: "0.7.2" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" - url: "https://pub.dev" - source: hosted - version: "14.2.5" -sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" diff --git a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/pubspec.yaml b/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/pubspec.yaml deleted file mode 100644 index 5fc02c8cf..000000000 --- a/packages/instabug_private_views/example-hybrid-ios-app/my_flutter/pubspec.yaml +++ /dev/null @@ -1,80 +0,0 @@ -name: my_flutter -description: "A new Flutter module project." - -version: 1.0.0+1 - -environment: - sdk: ">=2.12.0 <4.0.0" - -dependency_overrides: - instabug_flutter: - path: '../../../instabug_flutter' - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.8 - instabug_flutter: - path: '../../../instabug_flutter' - instabug_private_views: - path: '../../../instabug_private_views' -dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^4.0.0 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add Flutter specific assets to your application, add an assets section, - # like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/to/resolution-aware-images - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/to/asset-from-package - - # To add Flutter specific custom fonts to your application, add a fonts - # section here, in this "flutter" section. Each entry in this list should - # have a "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/to/font-from-package - - - # This section identifies your Flutter project as a module meant for - # embedding in a native host app. These identifiers should _not_ ordinarily - # be changed after generation - they are used to ensure that the tooling can - # maintain consistency when adding or modifying assets and plugins. - # They also do not have any bearing on your native host application's - # identifiers, which may be completely independent or the same as these. - module: - androidX: true - androidPackage: com.example.my_flutter - iosBundleIdentifier: com.example.myFlutter diff --git a/packages/instabug_private_views/example/.metadata b/packages/instabug_private_views/example/.metadata deleted file mode 100644 index c2aa44bdb..000000000 --- a/packages/instabug_private_views/example/.metadata +++ /dev/null @@ -1,45 +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: "603104015dd692ea3403755b55d07813d5cf8965" - channel: "stable" - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: android - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: ios - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: linux - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: macos - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: web - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - platform: windows - create_revision: 603104015dd692ea3403755b55d07813d5cf8965 - base_revision: 603104015dd692ea3403755b55d07813d5cf8965 - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/packages/instabug_private_views/example/android/app/src/main/kotlin/com/instabug/example/MainActivity.kt b/packages/instabug_private_views/example/android/app/src/main/kotlin/com/instabug/example/MainActivity.kt deleted file mode 100644 index 3759d1c71..000000000 --- a/packages/instabug_private_views/example/android/app/src/main/kotlin/com/instabug/example/MainActivity.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.instabug.example - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() diff --git a/packages/instabug_private_views/example/android/build.gradle b/packages/instabug_private_views/example/android/build.gradle deleted file mode 100644 index 3b7cbec9f..000000000 --- a/packages/instabug_private_views/example/android/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = "../build" -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(":app") - tasks.withType(Test) { - // Prevent tests in moduleA from running - if (project.name == 'video_player_android') { - exclude '**/*' - } - } -} - -tasks.register("clean", Delete) { - delete rootProject.buildDir -} \ No newline at end of file diff --git a/packages/instabug_private_views/example/android/gradle.properties b/packages/instabug_private_views/example/android/gradle.properties deleted file mode 100644 index 259717082..000000000 --- a/packages/instabug_private_views/example/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError -android.useAndroidX=true -android.enableJetifier=true diff --git a/packages/instabug_private_views/example/android/gradlew b/packages/instabug_private_views/example/android/gradlew deleted file mode 100755 index 9d82f7891..000000000 --- a/packages/instabug_private_views/example/android/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/packages/instabug_private_views/example/android/gradlew.bat b/packages/instabug_private_views/example/android/gradlew.bat deleted file mode 100644 index 8a0b282aa..000000000 --- a/packages/instabug_private_views/example/android/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/packages/instabug_private_views/example/android/settings.gradle b/packages/instabug_private_views/example/android/settings.gradle deleted file mode 100644 index b9e43bd37..000000000 --- a/packages/instabug_private_views/example/android/settings.gradle +++ /dev/null @@ -1,25 +0,0 @@ -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - }() - - includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.1.0" apply false - id "org.jetbrains.kotlin.android" version "1.8.22" apply false -} - -include ":app" diff --git a/packages/instabug_private_views/example/assets/img.png b/packages/instabug_private_views/example/assets/img.png deleted file mode 100644 index fff04770f..000000000 Binary files a/packages/instabug_private_views/example/assets/img.png and /dev/null differ diff --git a/packages/instabug_private_views/example/ios/Flutter/Debug.xcconfig b/packages/instabug_private_views/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index ec97fc6f3..000000000 --- a/packages/instabug_private_views/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/instabug_private_views/example/ios/Flutter/Release.xcconfig b/packages/instabug_private_views/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index c4855bfe2..000000000 --- a/packages/instabug_private_views/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/instabug_private_views/example/ios/Podfile b/packages/instabug_private_views/example/ios/Podfile deleted file mode 100644 index 8b43e9c1b..000000000 --- a/packages/instabug_private_views/example/ios/Podfile +++ /dev/null @@ -1,46 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '12.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! -pod 'Instabug', :podspec => 'https://ios-releases.instabug.com/custom/feature-flutter-private-views-base/14.0.0/Instabug.podspec' - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - pod 'OCMock', '3.6' - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - end -end diff --git a/packages/instabug_private_views/example/ios/Podfile.lock b/packages/instabug_private_views/example/ios/Podfile.lock deleted file mode 100644 index 4ec18dae9..000000000 --- a/packages/instabug_private_views/example/ios/Podfile.lock +++ /dev/null @@ -1,49 +0,0 @@ -PODS: - - Flutter (1.0.0) - - Instabug (14.0.0) - - instabug_flutter (14.0.0): - - Flutter - - Instabug (= 14.0.0) - - instabug_private_views (0.0.1): - - Flutter - - instabug_flutter - - OCMock (3.6) - - video_player_avfoundation (0.0.1): - - Flutter - - FlutterMacOS - -DEPENDENCIES: - - Flutter (from `Flutter`) - - Instabug (from `https://ios-releases.instabug.com/custom/feature-flutter-private-views-base/14.0.0/Instabug.podspec`) - - instabug_flutter (from `.symlinks/plugins/instabug_flutter/ios`) - - instabug_private_views (from `.symlinks/plugins/instabug_private_views/ios`) - - OCMock (= 3.6) - - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`) - -SPEC REPOS: - trunk: - - OCMock - -EXTERNAL SOURCES: - Flutter: - :path: Flutter - Instabug: - :podspec: https://ios-releases.instabug.com/custom/feature-flutter-private-views-base/14.0.0/Instabug.podspec - instabug_flutter: - :path: ".symlinks/plugins/instabug_flutter/ios" - instabug_private_views: - :path: ".symlinks/plugins/instabug_private_views/ios" - video_player_avfoundation: - :path: ".symlinks/plugins/video_player_avfoundation/darwin" - -SPEC CHECKSUMS: - Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - Instabug: 9d2b06afbadfbd4630bc0116dc27d84360ed70b0 - instabug_flutter: ff8ab5ff34a476b1d2d887478ec190cda962b973 - instabug_private_views: df53ff3f1cc842cb686d43e077099d3b36426a7f - OCMock: 5ea90566be239f179ba766fd9fbae5885040b992 - video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 - -PODFILE CHECKSUM: 38cf660255aba2d321a6f139341d5a867e19b769 - -COCOAPODS: 1.14.3 diff --git a/packages/instabug_private_views/example/ios/RunnerTests/RunnerTests-Bridging-Header.h b/packages/instabug_private_views/example/ios/RunnerTests/RunnerTests-Bridging-Header.h deleted file mode 100644 index 1b2cb5d6d..000000000 --- a/packages/instabug_private_views/example/ios/RunnerTests/RunnerTests-Bridging-Header.h +++ /dev/null @@ -1,4 +0,0 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// - diff --git a/packages/instabug_private_views/example/lib/main.dart b/packages/instabug_private_views/example/lib/main.dart deleted file mode 100644 index 9ae8442dd..000000000 --- a/packages/instabug_private_views/example/lib/main.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:instabug_flutter/instabug_flutter.dart'; -import 'package:instabug_private_views/instabug_private_view.dart'; - -import 'package:instabug_private_views_example/private_view_page.dart'; - -void main() { - runZonedGuarded( - () { - WidgetsFlutterBinding.ensureInitialized(); - - Instabug.init( - token: 'ed6f659591566da19b67857e1b9d40ab', - invocationEvents: [InvocationEvent.floatingButton], - debugLogsLevel: LogLevel.verbose, - ); - - FlutterError.onError = (FlutterErrorDetails details) { - Zone.current.handleUncaughtError(details.exception, details.stack!); - }; - - enableInstabugMaskingPrivateViews(); - runApp(const PrivateViewPage()); - }, - CrashReporting.reportCrash, - ); -} diff --git a/packages/instabug_private_views/example/lib/private_view_page.dart b/packages/instabug_private_views/example/lib/private_view_page.dart deleted file mode 100644 index be01f1ba3..000000000 --- a/packages/instabug_private_views/example/lib/private_view_page.dart +++ /dev/null @@ -1,153 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:instabug_private_views/instabug_private_view.dart'; -import 'package:video_player/video_player.dart'; - -class PrivateViewPage extends StatefulWidget { - const PrivateViewPage({Key? key}) : super(key: key); - - @override - _PrivateViewPageState createState() => _PrivateViewPageState(); -} - -class _PrivateViewPageState extends State { - late VideoPlayerController _controller; - - @override - void initState() { - super.initState(); - _controller = VideoPlayerController.networkUrl( - Uri.parse( - 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'), - )..initialize().then((_) { - setState(() {}); - }); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return MaterialApp( - debugShowCheckedModeBanner: false, - home: Scaffold( - appBar: AppBar(title: const Text("Private Views page")), - body: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox(height: 16), - InstabugPrivateView( - child: const Text( - 'Private TextView', - style: TextStyle(fontSize: 18), - textAlign: TextAlign.center, - ), - ), - const SizedBox(height: 16), - InstabugPrivateView( - child: ElevatedButton( - onPressed: () { - const snackBar = SnackBar( - content: Text('Hello, you clicked on a private button'), - ); - ScaffoldMessenger.of(context).showSnackBar(snackBar); - }, - child: const Text('I am a private button'), - ), - ), - const SizedBox(height: 16), - InstabugPrivateView( - child: Image.asset( - 'assets/img.png', - // Add this image to your assets folder - height: 100, - ), - ), - const SizedBox(height: 33), - InstabugPrivateView( - child: const TextField( - obscureText: true, - decoration: InputDecoration( - hintText: 'password', - labelText: 'Password', - border: OutlineInputBorder(), - ), - ), - ), - const SizedBox(height: 16), - const TextField( - keyboardType: TextInputType.emailAddress, - decoration: InputDecoration( - hintText: 'Email', - labelText: 'Email', - border: OutlineInputBorder(), - ), - ), - const SizedBox(height: 16), - Column( - children: [ - InstabugPrivateView( - child: const Text( - 'Private TextView in column', - style: TextStyle(fontSize: 18), - textAlign: TextAlign.center, - ), - ), - SizedBox( - height: 10, - ), - const Text( - 'TextView in column', - style: TextStyle(fontSize: 18), - textAlign: TextAlign.center, - ), - ], - ), - const SizedBox(height: 24), - InstabugPrivateView( - child: Container( - height: 300, - child: _controller.value.isInitialized - ? AspectRatio( - aspectRatio: _controller.value.aspectRatio, - child: VideoPlayer(_controller), - ) - : const Center(child: CircularProgressIndicator()), - ), - ), - const SizedBox(height: 24), - const SizedBox(height: 24), - const SizedBox(height: 24), - SizedBox( - height: 200, - child: CustomScrollView( - slivers: [ - InstabugSliverPrivateView( - sliver: SliverToBoxAdapter( - child: Container( - color: Colors.red, - child: const Text( - "Private Sliver Widget", - style: TextStyle(fontSize: 18), - textAlign: TextAlign.center, - ), - ), - ), - ) - ], - ), - ) - ], - ), - ), - ), - ), - ); - } -} diff --git a/packages/instabug_private_views/example/lib/widget/instabug_button.dart b/packages/instabug_private_views/example/lib/widget/instabug_button.dart deleted file mode 100644 index 97e434061..000000000 --- a/packages/instabug_private_views/example/lib/widget/instabug_button.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; - -class InstabugButton extends StatelessWidget { - const InstabugButton({ - Key? key, - required this.text, - this.onPressed, - this.fontSize, - this.margin, - }) : super(key: key); - - const InstabugButton.smallFontSize({ - Key? key, - required this.text, - this.onPressed, - this.fontSize = 10.0, - this.margin, - }) : super(key: key); - - final String text; - final Function()? onPressed; - final double? fontSize; - - final EdgeInsetsGeometry? margin; - - @override - Widget build(BuildContext context) { - return Container( - width: double.infinity, - margin: margin ?? - const EdgeInsets.symmetric( - horizontal: 20.0, - ), - child: ElevatedButton( - onPressed: onPressed, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.lightBlue, - foregroundColor: Colors.white, - textStyle: Theme.of(context) - .textTheme - .labelLarge - ?.copyWith(fontSize: fontSize), - ), - child: Text(text), - ), - ); - } -} diff --git a/packages/instabug_private_views/example/lib/widget/instabug_text_field.dart b/packages/instabug_private_views/example/lib/widget/instabug_text_field.dart deleted file mode 100644 index 3d01cc623..000000000 --- a/packages/instabug_private_views/example/lib/widget/instabug_text_field.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/material.dart'; - -class InstabugTextField extends StatelessWidget { - const InstabugTextField({ - Key? key, - required this.label, - required this.controller, - this.labelStyle, - this.margin, - this.keyboardType, - this.validator, - }) : super(key: key); - - final String label; - final TextEditingController controller; - final EdgeInsetsGeometry? margin; - final TextStyle? labelStyle; - final TextInputType? keyboardType; - final FormFieldValidator? validator; - - @override - Widget build(BuildContext context) { - return Container( - margin: margin ?? - const EdgeInsets.symmetric( - horizontal: 20.0, - ), - child: TextFormField( - controller: controller, - keyboardType: keyboardType, - validator: validator, - decoration: InputDecoration( - labelText: label, - labelStyle: labelStyle ?? Theme.of(context).textTheme.labelLarge, - suffixIcon: IconButton( - onPressed: controller.clear, - iconSize: 12.0, - icon: const Icon( - Icons.clear, - ), - ), - ), - ), - ); - } -} diff --git a/packages/instabug_private_views/example/lib/widget/section_title.dart b/packages/instabug_private_views/example/lib/widget/section_title.dart deleted file mode 100644 index 2c0509fa8..000000000 --- a/packages/instabug_private_views/example/lib/widget/section_title.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/material.dart'; - -class SectionTitle extends StatelessWidget { - final String text; - - const SectionTitle(this.text, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - alignment: Alignment.centerLeft, - margin: const EdgeInsets.only(top: 20.0, left: 20.0), - child: Text( - text, - textAlign: TextAlign.left, - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), - ), - ); - } -} diff --git a/packages/instabug_private_views/ios/Classes/InstabugPrivateViewsPlugin.h b/packages/instabug_private_views/ios/Classes/InstabugPrivateViewsPlugin.h deleted file mode 100644 index f1ab588ce..000000000 --- a/packages/instabug_private_views/ios/Classes/InstabugPrivateViewsPlugin.h +++ /dev/null @@ -1,4 +0,0 @@ -#import - -@interface InstabugPrivateViewsPlugin : NSObject -@end diff --git a/packages/instabug_private_views/ios/Classes/InstabugPrivateViewsPlugin.m b/packages/instabug_private_views/ios/Classes/InstabugPrivateViewsPlugin.m deleted file mode 100644 index 833cea6de..000000000 --- a/packages/instabug_private_views/ios/Classes/InstabugPrivateViewsPlugin.m +++ /dev/null @@ -1,13 +0,0 @@ -#import "InstabugPrivateViewsPlugin.h" -#import "PrivateViewApi.h" -#import "PrivateViewHostApi.h" -@implementation InstabugPrivateViewsPlugin -+ (void)registerWithRegistrar:(NSObject*)registrar { - PrivateViewApi* privateViewApi = InitPrivateViewApi([registrar messenger],registrar); - InitPrivateViewApi([registrar messenger], registrar); - InitPrivateViewHostApi([registrar messenger], privateViewApi); - -} - - -@end diff --git a/packages/instabug_private_views/ios/Classes/instabug_private_views-Bridging-Header.h b/packages/instabug_private_views/ios/Classes/instabug_private_views-Bridging-Header.h deleted file mode 100644 index 1b2cb5d6d..000000000 --- a/packages/instabug_private_views/ios/Classes/instabug_private_views-Bridging-Header.h +++ /dev/null @@ -1,4 +0,0 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// - diff --git a/packages/instabug_private_views/lib/instabug_private_view.dart b/packages/instabug_private_views/lib/instabug_private_view.dart deleted file mode 100644 index 0be5a6278..000000000 --- a/packages/instabug_private_views/lib/instabug_private_view.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:instabug_private_views/src/generated/instabug_private_view.api.g.dart'; -import 'package:instabug_private_views/src/private_views_manager.dart'; - -export 'src/instabug_private_view.dart'; -export 'src/instabug_sliver_private_view.dart'; - -void enableInstabugMaskingPrivateViews() { - final api = InstabugPrivateViewHostApi(); - api.init(); - InstabugPrivateViewFlutterApi.setup(PrivateViewsManager.I); -} diff --git a/packages/instabug_private_views/lib/src/instabug_private_view.dart b/packages/instabug_private_views/lib/src/instabug_private_view.dart deleted file mode 100644 index 3d16ee1b1..000000000 --- a/packages/instabug_private_views/lib/src/instabug_private_view.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:instabug_private_views/src/private_views_manager.dart'; -import 'package:instabug_private_views/src/visibility_detector/visibility_detector.dart'; - -class InstabugPrivateView extends StatefulWidget { - final Widget child; - - // Making the constructor const prevents the VisibilityDetector from detecting changes in the view, - // ignore: prefer_const_constructors_in_immutables - InstabugPrivateView({required this.child}) : super(key: null); - - @override - State createState() => _InstabugPrivateViewState(); -} - -class _InstabugPrivateViewState extends State { - final GlobalKey _visibilityDetectorKey = GlobalKey(); - final GlobalKey _childKey = GlobalKey(); - - @override - void initState() { - _addPrivateView(); - super.initState(); - } - - @override - void dispose() { - _removePrivateView(); - super.dispose(); - } - - void _addPrivateView() { - PrivateViewsManager.I.mask(_childKey); - } - - void _removePrivateView() { - PrivateViewsManager.I.unMask(_childKey); - } - - void _onVisibilityChanged(bool isVisible) { - if (isVisible) { - _addPrivateView(); - } else { - _removePrivateView(); - } - } - - @override - Widget build(BuildContext context) { - return VisibilityDetector( - key: _visibilityDetectorKey, - onVisibilityChanged: _onVisibilityChanged, - child: KeyedSubtree(key: _childKey, child: widget.child), - ); - } -} diff --git a/packages/instabug_private_views/lib/src/instabug_sliver_private_view.dart b/packages/instabug_private_views/lib/src/instabug_sliver_private_view.dart deleted file mode 100644 index bc0237513..000000000 --- a/packages/instabug_private_views/lib/src/instabug_sliver_private_view.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:instabug_private_views/src/private_views_manager.dart'; -import 'package:instabug_private_views/src/visibility_detector/sliver_visibility_detector.dart'; - -class InstabugSliverPrivateView extends StatefulWidget { - final Widget sliver; - - // Making the constructor const prevents the VisibilityDetector from detecting changes in the view, - // ignore: prefer_const_constructors_in_immutables, use_super_parameters - InstabugSliverPrivateView({Key? key, required this.sliver}) : super(key: key); - - @override - State createState() => - _InstabugSliverPrivateViewState(); -} - -class _InstabugSliverPrivateViewState extends State { - final key = GlobalKey(); - final GlobalKey _childKey = GlobalKey(); - - @override - void dispose() { - _removePrivateView(); - super.dispose(); - } - - @override - void initState() { - _addPrivateView(); - super.initState(); - } - - void _addPrivateView() { - PrivateViewsManager.I.mask(_childKey); - } - - void _removePrivateView() { - PrivateViewsManager.I.unMask(_childKey); - } - - void _onVisibilityChanged(bool isVisible) { - if (isVisible) { - _addPrivateView(); - } else { - _removePrivateView(); - } - } - - @override - Widget build(BuildContext context) { - return SliverVisibilityDetector( - key: key, - onVisibilityChanged: _onVisibilityChanged, - sliver: KeyedSubtree(key: _childKey, child: widget.sliver), - ); - } -} diff --git a/packages/instabug_private_views/lib/src/private_views_manager.dart b/packages/instabug_private_views/lib/src/private_views_manager.dart deleted file mode 100644 index 50815fbe8..000000000 --- a/packages/instabug_private_views/lib/src/private_views_manager.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:instabug_private_views/src/generated/instabug_private_view.api.g.dart'; - -/// responsible for masking views -/// before they are sent to the native SDKs. -class PrivateViewsManager implements InstabugPrivateViewFlutterApi { - PrivateViewsManager._(); - - static PrivateViewsManager _instance = PrivateViewsManager._(); - - static PrivateViewsManager get instance => _instance; - - /// Shorthand for [instance] - static PrivateViewsManager get I => instance; - - final Set _keys = {}; - - @visibleForTesting - // ignore: use_setters_to_change_properties - static void setInstance(PrivateViewsManager instance) { - _instance = instance; - } - - Rect? getLayoutRectInfoFromKey(GlobalKey key) { - final renderObject = key.currentContext?.findRenderObject(); - - if (renderObject == null) { - return null; - } - - final globalOffset = _getRenderGlobalOffset(renderObject); - - if (renderObject is RenderProxyBox) { - if (renderObject.child == null) { - return null; - } - - return MatrixUtils.transformRect( - renderObject.child!.getTransformTo(renderObject), - Offset.zero & renderObject.child!.size, - ).shift(globalOffset); - } - - return renderObject.paintBounds.shift(globalOffset); - } - - // The is the same implementation used in RenderBox.localToGlobal (a subclass of RenderObject) - Offset _getRenderGlobalOffset(RenderObject renderObject) { - return MatrixUtils.transformPoint( - renderObject.getTransformTo(null), - Offset.zero, - ); - } - - void mask(GlobalKey key) { - _keys.add(key); - } - - void unMask(GlobalKey key) { - _keys.remove(key); - } - - @override - List getPrivateViews() { - final result = []; - - for (final view in _keys) { - final rect = getLayoutRectInfoFromKey(view); - - if (rect == null) continue; - - result.addAll([ - rect.left, - rect.top, - rect.right, - rect.bottom, - ]); - } - - return result; - } -} diff --git a/packages/instabug_private_views/lib/src/visibility_detector/base_render_visibility_detector.dart b/packages/instabug_private_views/lib/src/visibility_detector/base_render_visibility_detector.dart deleted file mode 100644 index 46b901235..000000000 --- a/packages/instabug_private_views/lib/src/visibility_detector/base_render_visibility_detector.dart +++ /dev/null @@ -1,266 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:instabug_private_views/src/visibility_detector/visibillity_utils.dart'; - -typedef VisibilityChangedCallback = void Function(bool isVisible); - -mixin RenderVisibilityDetectorBase on RenderObject { - static int? get debugUpdateCount { - if (!kDebugMode) { - return null; - } - return _updates.length; - } - - static Duration updateInterval = const Duration(milliseconds: 500); - static final Map _updates = {}; - static final Map _lastVisibility = {}; - - static void forget(Key key) { - _updates.remove(key); - _lastVisibility.remove(key); - - if (_updates.isEmpty) { - _timer?.cancel(); - _timer = null; - } - } - - static Timer? _timer; - - static void _handleTimer() { - _timer = null; - // Ensure that work is done between frames so that calculations are - // performed from a consistent state. We use `scheduleTask` here instead - // of `addPostFrameCallback` or `scheduleFrameCallback` so that work will - // be done even if a new frame isn't scheduled and without unnecessarily - // scheduling a new frame. - SchedulerBinding.instance.scheduleTask( - _processCallbacks, - Priority.touch, - ); - } - - /// Executes visibility callbacks for all updated instances. - static void _processCallbacks() { - for (final callback in _updates.values) { - callback(); - } - - _updates.clear(); - } - - void _fireCallback(ContainerLayer? layer, Rect bounds) { - final oldInfo = _lastVisibility[key]; - final visible = _determineVisibility(layer, bounds); - - if (visible == oldInfo) { - return; - } - - if (visible) { - _lastVisibility[key] = visible; - } else { - // Track only visible items so that the map does not grow unbounded. - if (oldInfo != null) { - _lastVisibility.remove(key); - } - } - - onVisibilityChanged?.call(visible); - } - - /// The key for the corresponding [VisibilityDetector] widget. - Key get key; - - VoidCallback? _compositionCallbackCanceller; - - VisibilityChangedCallback? _onVisibilityChanged; - - // ignore: use_setters_to_change_properties - void init({required VisibilityChangedCallback? visibilityChangedCallback}) { - _onVisibilityChanged = visibilityChangedCallback; - } - - VisibilityChangedCallback? get onVisibilityChanged => _onVisibilityChanged; - - set onVisibilityChanged(VisibilityChangedCallback? value) { - _compositionCallbackCanceller?.call(); - _compositionCallbackCanceller = null; - _onVisibilityChanged = value; - - if (value == null) { - forget(key); - } else { - markNeedsPaint(); - // If an update is happening and some ancestor no longer paints this RO, - // the markNeedsPaint above will never cause the composition callback to - // fire and we could miss a hide event. This schedule will get - // over-written by subsequent updates in paint, if paint is called. - _scheduleUpdate(); - } - } - - int _debugScheduleUpdateCount = 0; - - /// The number of times the schedule update callback has been invoked from - /// [Layer.addCompositionCallback]. - /// - /// This is used for testing, and always returns null outside of debug mode. - @visibleForTesting - int? get debugScheduleUpdateCount { - if (kDebugMode) { - return _debugScheduleUpdateCount; - } - return null; - } - - void _scheduleUpdate([ContainerLayer? layer]) { - if (kDebugMode) { - _debugScheduleUpdateCount += 1; - } - final isFirstUpdate = _updates.isEmpty; - _updates[key] = () { - if (bounds == null) { - return; - } - _fireCallback(layer, bounds!); - }; - - if (updateInterval == Duration.zero) { - if (isFirstUpdate) { - // We're about to render a frame, so a post-frame callback is guaranteed - // to fire and will give us the better immediacy than `scheduleTask`. - SchedulerBinding.instance.addPostFrameCallback((timeStamp) { - _processCallbacks(); - }); - } - } else if (_timer == null) { - // We use a normal [Timer] instead of a [RestartableTimer] so that changes - // to the update duration will be picked up automatically. - _timer = Timer(updateInterval, _handleTimer); - } else { - assert(_timer!.isActive); - } - } - - bool _determineVisibility(ContainerLayer? layer, Rect bounds) { - if (_disposed || layer == null || layer.attached == false || !attached) { - // layer is detached and thus invisible. - return false; - } - final transform = Matrix4.identity(); - - // Check if any ancestors decided to skip painting this RenderObject. - if (parent != null) { - // ignore: unnecessary_cast - var ancestor = parent! as RenderObject; - RenderObject child = this; - while (ancestor.parent != null) { - if (!ancestor.paintsChild(child)) { - return false; - } - child = ancestor; - // ignore: unnecessary_cast - ancestor = ancestor.parent! as RenderObject; - } - } - - // Create a list of Layers from layer to the root, excluding the root - // since that has the DPR transform and we want to work with logical pixels. - // Add one extra leaf layer so that we can apply the transform of `layer` - // to the matrix. - ContainerLayer? ancestor = layer; - final ancestors = [ContainerLayer()]; - while (ancestor != null && ancestor.parent != null) { - ancestors.add(ancestor); - ancestor = ancestor.parent; - } - - var clip = Rect.largest; - for (var index = ancestors.length - 1; index > 0; index -= 1) { - final parent = ancestors[index]; - final child = ancestors[index - 1]; - final parentClip = parent.describeClipBounds(); - if (parentClip != null) { - clip = clip.intersect(MatrixUtils.transformRect(transform, parentClip)); - } - parent.applyTransform(child, transform); - } - - // Apply whatever transform/clip was on the canvas when painting. - if (_lastPaintClipBounds != null) { - clip = clip.intersect( - MatrixUtils.transformRect( - transform, - _lastPaintClipBounds!, - ), - ); - } - if (_lastPaintTransform != null) { - transform.multiply(_lastPaintTransform!); - } - return isWidgetVisible( - MatrixUtils.transformRect(transform, bounds), - clip, - ); - } - - /// Used to get the bounds of the render object when it is time to update - /// clients about visibility. - /// - /// A null value means bounds are not available. - Rect? get bounds; - - Matrix4? _lastPaintTransform; - Rect? _lastPaintClipBounds; - - @override - void paint(PaintingContext context, Offset offset) { - if (onVisibilityChanged != null) { - _lastPaintClipBounds = context.canvas.getLocalClipBounds(); - _lastPaintTransform = - Matrix4.fromFloat64List(context.canvas.getTransform()) - ..translate(offset.dx, offset.dy); - - _compositionCallbackCanceller?.call(); - _compositionCallbackCanceller = - context.addCompositionCallback((Layer layer) { - assert(!debugDisposed!); - final container = layer is ContainerLayer ? layer : layer.parent; - _scheduleUpdate(container); - }); - } - super.paint(context, offset); - } - - bool _disposed = false; - - @override - void dispose() { - _compositionCallbackCanceller?.call(); - _compositionCallbackCanceller = null; - _disposed = true; - super.dispose(); - } -} - -class RenderVisibilityDetector extends RenderProxyBox - with RenderVisibilityDetectorBase { - RenderVisibilityDetector({ - RenderBox? child, - required this.key, - required VisibilityChangedCallback? onVisibilityChanged, - }) : super(child) { - _onVisibilityChanged = onVisibilityChanged; - } - - @override - final Key key; - - @override - Rect? get bounds => hasSize ? semanticBounds : null; -} diff --git a/packages/instabug_private_views/lib/src/visibility_detector/sliver_visibility_detector.dart b/packages/instabug_private_views/lib/src/visibility_detector/sliver_visibility_detector.dart deleted file mode 100644 index facdd68d1..000000000 --- a/packages/instabug_private_views/lib/src/visibility_detector/sliver_visibility_detector.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'dart:math' as math; - -import 'package:flutter/rendering.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:instabug_private_views/src/visibility_detector/base_render_visibility_detector.dart'; - -class RenderSliverVisibilityDetector extends RenderProxySliver - with RenderVisibilityDetectorBase { - RenderSliverVisibilityDetector({ - RenderSliver? sliver, - required this.key, - required VisibilityChangedCallback? onVisibilityChanged, - }) : super(sliver) { - init(visibilityChangedCallback: onVisibilityChanged); - } - - @override - final Key key; - - @override - Rect? get bounds { - if (geometry == null) { - return null; - } - - Size widgetSize; - Offset widgetOffset; - switch (applyGrowthDirectionToAxisDirection( - constraints.axisDirection, - constraints.growthDirection, - )) { - case AxisDirection.down: - widgetOffset = Offset(0, -constraints.scrollOffset); - widgetSize = Size(constraints.crossAxisExtent, geometry!.scrollExtent); - break; - case AxisDirection.up: - final startOffset = geometry!.paintExtent + - constraints.scrollOffset - - geometry!.scrollExtent; - widgetOffset = Offset(0, math.min(startOffset, 0)); - widgetSize = Size(constraints.crossAxisExtent, geometry!.scrollExtent); - break; - case AxisDirection.right: - widgetOffset = Offset(-constraints.scrollOffset, 0); - widgetSize = Size(geometry!.scrollExtent, constraints.crossAxisExtent); - break; - case AxisDirection.left: - final startOffset = geometry!.paintExtent + - constraints.scrollOffset - - geometry!.scrollExtent; - widgetOffset = Offset(math.min(startOffset, 0), 0); - widgetSize = Size(geometry!.scrollExtent, constraints.crossAxisExtent); - break; - } - return widgetOffset & widgetSize; - } -} - -class SliverVisibilityDetector extends SingleChildRenderObjectWidget { - const SliverVisibilityDetector({ - required Key key, - required Widget sliver, - required this.onVisibilityChanged, - }) : super(key: key, child: sliver); - - final VisibilityChangedCallback? onVisibilityChanged; - - @override - RenderSliverVisibilityDetector createRenderObject(BuildContext context) { - return RenderSliverVisibilityDetector( - key: key!, - onVisibilityChanged: onVisibilityChanged, - ); - } - - @override - void updateRenderObject( - BuildContext context, - RenderSliverVisibilityDetector renderObject, - ) { - assert(renderObject.key == key); - renderObject.onVisibilityChanged = onVisibilityChanged; - } -} diff --git a/packages/instabug_private_views/lib/src/visibility_detector/visibility_detector.dart b/packages/instabug_private_views/lib/src/visibility_detector/visibility_detector.dart deleted file mode 100644 index 16b83b025..000000000 --- a/packages/instabug_private_views/lib/src/visibility_detector/visibility_detector.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:flutter/rendering.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:instabug_private_views/src/visibility_detector/base_render_visibility_detector.dart'; - -class RenderVisibilityDetector extends RenderProxyBox - with RenderVisibilityDetectorBase { - RenderVisibilityDetector({ - RenderBox? child, - required this.key, - required VisibilityChangedCallback? onVisibilityChanged, - }) : super(child) { - init(visibilityChangedCallback: onVisibilityChanged); - } - - @override - final Key key; - - @override - Rect? get bounds => hasSize ? semanticBounds : null; -} - -class VisibilityDetector extends SingleChildRenderObjectWidget { - const VisibilityDetector({ - required Key key, - required Widget child, - required this.onVisibilityChanged, - }) : super(key: key, child: child); - - /// The callback to invoke when this widget's visibility changes. - final VisibilityChangedCallback? onVisibilityChanged; - - @override - RenderVisibilityDetector createRenderObject(BuildContext context) { - return RenderVisibilityDetector( - key: key!, - onVisibilityChanged: onVisibilityChanged, - ); - } - - @override - void updateRenderObject( - BuildContext context, - RenderVisibilityDetector renderObject, - ) { - assert(renderObject.key == key); - renderObject.onVisibilityChanged = onVisibilityChanged; - } -} diff --git a/packages/instabug_private_views/lib/src/visibility_detector/visibillity_utils.dart b/packages/instabug_private_views/lib/src/visibility_detector/visibillity_utils.dart deleted file mode 100644 index 855f625cf..000000000 --- a/packages/instabug_private_views/lib/src/visibility_detector/visibillity_utils.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/widgets.dart'; - -bool isWidgetVisible( - Rect widgetBounds, - Rect clipRect, -) { - final overlaps = widgetBounds.overlaps(clipRect); - // Compute the intersection in the widget's local coordinates. - final visibleBounds = overlaps - ? widgetBounds.intersect(clipRect).shift(-widgetBounds.topLeft) - : Rect.zero; - final visibleArea = _area(visibleBounds.size); - final maxVisibleArea = _area(widgetBounds.size); - - if (_floatNear(maxVisibleArea, 0)) { - return false; - } - - final visibleFraction = visibleArea / maxVisibleArea; - - if (_floatNear(visibleFraction, 0)) { - return false; - } else if (_floatNear(visibleFraction, 1)) { - return true; - } - - return true; -} - -/// Computes the area of a rectangle of the specified dimensions. -double _area(Size size) { - assert(size.width >= 0); - assert(size.height >= 0); - return size.width * size.height; -} - -/// Returns whether two floating-point values are approximately equal. -bool _floatNear(double f1, double f2) { - final absDiff = (f1 - f2).abs(); - return absDiff <= _kDefaultTolerance || - (absDiff / max(f1.abs(), f2.abs()) <= _kDefaultTolerance); -} - -const _kDefaultTolerance = 0.01; diff --git a/packages/instabug_private_views/pubspec.lock b/packages/instabug_private_views/pubspec.lock deleted file mode 100644 index 76aedff0e..000000000 --- a/packages/instabug_private_views/pubspec.lock +++ /dev/null @@ -1,716 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a - url: "https://pub.dev" - source: hosted - version: "61.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 - url: "https://pub.dev" - source: hosted - version: "5.13.0" - args: - dependency: transitive - description: - name: args - sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 - url: "https://pub.dev" - source: hosted - version: "2.6.0" - async: - dependency: transitive - description: - name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - build: - dependency: transitive - description: - name: build - sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - build_config: - dependency: transitive - description: - name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 - url: "https://pub.dev" - source: hosted - version: "1.1.1" - build_daemon: - dependency: transitive - description: - name: build_daemon - sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" - url: "https://pub.dev" - source: hosted - version: "2.4.2" - build_runner: - dependency: "direct dev" - description: - name: build_runner - sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" - url: "https://pub.dev" - source: hosted - version: "2.4.13" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 - url: "https://pub.dev" - source: hosted - version: "7.3.2" - built_collection: - dependency: transitive - description: - name: built_collection - sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" - url: "https://pub.dev" - source: hosted - version: "5.1.1" - built_value: - dependency: transitive - description: - name: built_value - sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb - url: "https://pub.dev" - source: hosted - version: "8.9.2" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - checked_yaml: - dependency: transitive - description: - name: checked_yaml - sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff - url: "https://pub.dev" - source: hosted - version: "2.0.3" - cli_util: - dependency: transitive - description: - name: cli_util - sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c - url: "https://pub.dev" - source: hosted - version: "0.4.2" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - code_builder: - dependency: transitive - description: - name: code_builder - sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" - url: "https://pub.dev" - source: hosted - version: "4.10.1" - collection: - dependency: transitive - description: - name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" - source: hosted - version: "1.18.0" - convert: - dependency: transitive - description: - name: convert - sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 - url: "https://pub.dev" - source: hosted - version: "3.1.2" - coverage: - dependency: transitive - description: - name: coverage - sha256: "88b0fddbe4c92910fefc09cc0248f5e7f0cd23e450ded4c28f16ab8ee8f83268" - url: "https://pub.dev" - source: hosted - version: "1.10.0" - crypto: - dependency: transitive - description: - name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://pub.dev" - source: hosted - version: "3.0.6" - csslib: - dependency: transitive - description: - name: csslib - sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - dart_style: - dependency: transitive - description: - name: dart_style - sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" - url: "https://pub.dev" - source: hosted - version: "2.3.2" - fake_async: - dependency: "direct dev" - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - file: - dependency: transitive - description: - name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.dev" - source: hosted - version: "7.0.1" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.dev" - source: hosted - version: "1.1.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 - url: "https://pub.dev" - source: hosted - version: "4.0.0" - glob: - dependency: transitive - description: - name: glob - sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - graphs: - dependency: transitive - description: - name: graphs - sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" - url: "https://pub.dev" - source: hosted - version: "2.3.2" - html: - dependency: transitive - description: - name: html - sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" - url: "https://pub.dev" - source: hosted - version: "0.15.5" - http: - dependency: transitive - description: - name: http - sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 - url: "https://pub.dev" - source: hosted - version: "1.2.2" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - instabug_flutter: - dependency: "direct main" - description: - path: "../instabug_flutter" - relative: true - source: path - version: "14.0.0" - io: - dependency: transitive - description: - name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - js: - dependency: transitive - description: - name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf - url: "https://pub.dev" - source: hosted - version: "0.7.1" - json_annotation: - dependency: transitive - description: - name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - url: "https://pub.dev" - source: hosted - version: "4.9.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" - url: "https://pub.dev" - source: hosted - version: "10.0.5" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" - url: "https://pub.dev" - source: hosted - version: "3.0.5" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.dev" - source: hosted - version: "3.0.1" - lint: - dependency: "direct dev" - description: - name: lint - sha256: "4a539aa34ec5721a2c7574ae2ca0336738ea4adc2a34887d54b7596310b33c85" - url: "https://pub.dev" - source: hosted - version: "1.10.0" - lints: - dependency: transitive - description: - name: lints - sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 - url: "https://pub.dev" - source: hosted - version: "3.0.0" - logging: - dependency: transitive - description: - name: logging - sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 - url: "https://pub.dev" - source: hosted - version: "1.3.0" - markdown: - dependency: transitive - description: - name: markdown - sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051 - url: "https://pub.dev" - source: hosted - version: "7.2.2" - matcher: - dependency: transitive - description: - name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" - source: hosted - version: "0.12.16+1" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" - source: hosted - version: "0.11.1" - meta: - dependency: transitive - description: - name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 - url: "https://pub.dev" - source: hosted - version: "1.15.0" - mime: - dependency: transitive - description: - name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - mockito: - dependency: "direct dev" - description: - name: mockito - sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917" - url: "https://pub.dev" - source: hosted - version: "5.4.4" - node_preamble: - dependency: transitive - description: - name: node_preamble - sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - package_config: - dependency: transitive - description: - name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - pana: - dependency: "direct dev" - description: - name: pana - sha256: "3fc3fe8e7a9fd4827fa4d625a423eec95d305b2bc3538a3adf7fd6c49217af97" - url: "https://pub.dev" - source: hosted - version: "0.21.45" - path: - dependency: transitive - description: - name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" - source: hosted - version: "1.9.0" - pigeon: - dependency: "direct dev" - description: - name: pigeon - sha256: "6eb9702acc25d5ec340bd1b751e511e2982189dfc40c12e2d69db6e05bab03be" - url: "https://pub.dev" - source: hosted - version: "10.1.5" - pool: - dependency: transitive - description: - name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" - url: "https://pub.dev" - source: hosted - version: "1.5.1" - pub_semver: - dependency: transitive - description: - name: pub_semver - sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - pubspec_parse: - dependency: transitive - description: - name: pubspec_parse - sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 - url: "https://pub.dev" - source: hosted - version: "1.3.0" - retry: - dependency: transitive - description: - name: retry - sha256: "822e118d5b3aafed083109c72d5f484c6dc66707885e07c0fbcb8b986bba7efc" - url: "https://pub.dev" - source: hosted - version: "3.1.2" - safe_url_check: - dependency: transitive - description: - name: safe_url_check - sha256: "49a3e060a7869cbafc8f4845ca1ecbbaaa53179980a32f4fdfeab1607e90f41d" - url: "https://pub.dev" - source: hosted - version: "1.1.2" - shelf: - dependency: transitive - description: - name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 - url: "https://pub.dev" - source: hosted - version: "1.4.1" - shelf_packages_handler: - dependency: transitive - description: - name: shelf_packages_handler - sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - shelf_static: - dependency: transitive - description: - name: shelf_static - sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 - url: "https://pub.dev" - source: hosted - version: "1.1.3" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_gen: - dependency: transitive - description: - name: source_gen - sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" - url: "https://pub.dev" - source: hosted - version: "1.5.0" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b - url: "https://pub.dev" - source: hosted - version: "2.1.2" - source_maps: - dependency: transitive - description: - name: source_maps - sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" - url: "https://pub.dev" - source: hosted - version: "0.10.12" - source_span: - dependency: transitive - description: - name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" - source: hosted - version: "1.10.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" - source: hosted - version: "1.11.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" - source: hosted - version: "2.1.2" - stream_transform: - dependency: transitive - description: - name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - tar: - dependency: transitive - description: - name: tar - sha256: "22f67e2d77b51050436620b2a5de521c58ca6f0b75af1d9ab3c8cae2eae58fcd" - url: "https://pub.dev" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test: - dependency: transitive - description: - name: test - sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" - url: "https://pub.dev" - source: hosted - version: "1.25.7" - test_api: - dependency: transitive - description: - name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" - url: "https://pub.dev" - source: hosted - version: "0.7.2" - test_core: - dependency: transitive - description: - name: test_core - sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" - url: "https://pub.dev" - source: hosted - version: "0.6.4" - timing: - dependency: transitive - description: - name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" - url: "https://pub.dev" - source: hosted - version: "14.2.5" - watcher: - dependency: transitive - description: - name: watcher - sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - web: - dependency: transitive - description: - name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb - url: "https://pub.dev" - source: hosted - version: "1.1.0" - web_socket: - dependency: transitive - description: - name: web_socket - sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" - url: "https://pub.dev" - source: hosted - version: "0.1.6" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" - url: "https://pub.dev" - source: hosted - version: "3.0.1" - webkit_inspection_protocol: - dependency: transitive - description: - name: webkit_inspection_protocol - sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" - url: "https://pub.dev" - source: hosted - version: "1.2.1" - yaml: - dependency: transitive - description: - name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" - url: "https://pub.dev" - source: hosted - version: "3.1.2" -sdks: - dart: ">=3.5.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" diff --git a/packages/instabug_private_views/pubspec.yaml b/packages/instabug_private_views/pubspec.yaml deleted file mode 100644 index 60288d069..000000000 --- a/packages/instabug_private_views/pubspec.yaml +++ /dev/null @@ -1,36 +0,0 @@ -name: instabug_private_views -description: "An extension for the Instabug Flutter SDK that enables support for masking private views during screen capturing." -version: 1.0.1 -homepage: https://www.instabug.com -repository: https://github.com/Instabug/Instabug-Flutter -documentation: https://docs.instabug.com/docs/flutter-overview - -environment: - sdk: ">=2.14.0 <4.0.0" - flutter: '>=3.3.0' - -dependencies: - flutter: - sdk: flutter - instabug_flutter: - -dev_dependencies: - build_runner: ^2.0.3 - fake_async: '>=1.2.0 <1.4.0' - flutter_test: - sdk: flutter - lint: ^1.0.0 - # mockito v5.2.0 is needed for running Flutter 2 tests on CI - mockito: '>=5.2.0 <5.5.0' - pana: ^0.21.0 - # pigeon v3.0.0 is needed for running Flutter 2 tests on CI - pigeon: '>=3.0.0 <=10.1.5' - -flutter: - plugin: - platforms: - android: - package: com.instabug.instabug_private_views - pluginClass: InstabugPrivateViewsPlugin - ios: - pluginClass: InstabugPrivateViewsPlugin \ No newline at end of file diff --git a/packages/instabug_private_views/release.sh b/packages/instabug_private_views/release.sh deleted file mode 100755 index b30831736..000000000 --- a/packages/instabug_private_views/release.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -VERSION=$(egrep -o "version: ([0-9]-*.*)+[0-9]" pubspec.yaml | cut -d ":" -f 2) -if [ ! "${VERSION}" ] || [ -z "${VERSION}" ];then - echo "Instabug: err: Version Number not found." - exit 1 -else - mkdir -p $HOME/.config/dart - cat < $HOME/.config/dart/pub-credentials.json - ${PUB_CREDENTIALS} - -EOF - flutter packages pub publish -f -fi \ No newline at end of file diff --git a/packages/instabug_private_views/scripts/pigeon.sh b/packages/instabug_private_views/scripts/pigeon.sh deleted file mode 100644 index 5c7fb79b6..000000000 --- a/packages/instabug_private_views/scripts/pigeon.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -DIR_DART="lib/src/generated" -DIR_IOS="ios/Classes/Generated" -DIR_ANDROID="android/src/main/java/com/instabug/instabug_private_views/generated" -PKG_ANDROID="com.instabug.instabug_private_views.generated" - -mkdir -p $DIR_DART -mkdir -p $DIR_IOS -mkdir -p $DIR_ANDROID - -generate_pigeon() { - name_file=$1 - name_snake=$(basename $name_file .api.dart) - name_pascal=$(echo "$name_snake" | perl -pe 's/(^|_)./uc($&)/ge;s/_//g') - - dart run pigeon \ - --input "pigeons/$name_snake.api.dart" \ - --dart_out "$DIR_DART/$name_snake.api.g.dart" \ - --objc_header_out "$DIR_IOS/${name_pascal}Pigeon.h" \ - --objc_source_out "$DIR_IOS/${name_pascal}Pigeon.m" \ - --java_out "$DIR_ANDROID/${name_pascal}Pigeon.java" \ - --java_package $PKG_ANDROID || exit 1; - - echo "Generated $name_snake pigeon" - - # Generated files are not formatted by default, - # this affects pacakge score. - dart format "$DIR_DART/$name_snake.api.g.dart" -} - -for file in pigeons/** -do - generate_pigeon $file -done diff --git a/packages/instabug_private_views/test/instabug_private_view_test.dart b/packages/instabug_private_views/test/instabug_private_view_test.dart deleted file mode 100644 index 7f55c8c61..000000000 --- a/packages/instabug_private_views/test/instabug_private_view_test.dart +++ /dev/null @@ -1,82 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:instabug_private_views/src/instabug_private_view.dart'; -import 'package:instabug_private_views/src/private_views_manager.dart'; -import 'package:instabug_private_views/src/visibility_detector/base_render_visibility_detector.dart'; -import 'package:mockito/annotations.dart'; -import 'package:mockito/mockito.dart'; -import 'instabug_private_view_test.mocks.dart'; - -@GenerateMocks([PrivateViewsManager]) -void main() { - testWidgets('should mask the view when it is visible', (tester) async { - await tester.runAsync(() async { - final mock = MockPrivateViewsManager(); - RenderVisibilityDetectorBase.updateInterval = Duration.zero; - PrivateViewsManager.setInstance(mock); - await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: InstabugPrivateView( - child: const Text('Text invisible'), - ), - ), - ), - ); - - verify( - mock.mask(any), - ).called( - 2, - ); // one for initState and the other for visibility is shown is true - }); - }); - - testWidgets("should un-mask the view when it is invisible", (tester) async { - await tester.runAsync(() async { - final mock = MockPrivateViewsManager(); - RenderVisibilityDetectorBase.updateInterval = Duration.zero; - PrivateViewsManager.setInstance(mock); - var isVisible = true; - await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return ListView( - children: [ - Visibility( - visible: isVisible, - maintainState: true, - child: InstabugPrivateView( - child: const SizedBox( - width: 40, - height: 40, - ), - ), - ), - ElevatedButton( - onPressed: () { - setState(() { - isVisible = false; // make the widget invisible - }); - }, - child: const Text('Make invisible'), - ), - ], - ); - }, - ), - ), - ), - ); - await tester.tap(find.text('Make invisible')); - await tester.pump(const Duration(seconds: 1)); - verify( - mock.unMask(any), - ).called( - 1, - ); - }); - }); -} diff --git a/packages/instabug_private_views/test/instabug_sliver_private_view_test.dart b/packages/instabug_private_views/test/instabug_sliver_private_view_test.dart deleted file mode 100644 index 4e8bdab2b..000000000 --- a/packages/instabug_private_views/test/instabug_sliver_private_view_test.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:instabug_private_views/src/instabug_sliver_private_view.dart'; -import 'package:instabug_private_views/src/private_views_manager.dart'; -import 'package:instabug_private_views/src/visibility_detector/base_render_visibility_detector.dart'; -import 'package:mockito/mockito.dart'; - -import 'instabug_private_view_test.mocks.dart'; - -void main() { - testWidgets('should mask sliver view when it is visible', (tester) async { - await tester.runAsync(() async { - final mock = MockPrivateViewsManager(); - RenderVisibilityDetectorBase.updateInterval = Duration.zero; - PrivateViewsManager.setInstance(mock); - - await tester.pumpWidget( - MaterialApp( - home: CustomScrollView( - slivers: [ - InstabugSliverPrivateView( - sliver: const SliverToBoxAdapter( - child: SizedBox( - width: 20, - height: 40, - ), - ), - ), - ], - ), - ), - ); - - verify( - mock.mask(any), - ).called( - 2, - ); // one for initState and the other for visibility is shown is true - }); - }); - - testWidgets('should un-mask the sliver view when it is invisible', - (tester) async { - await tester.runAsync(() async { - final mock = MockPrivateViewsManager(); - RenderVisibilityDetectorBase.updateInterval = Duration.zero; - PrivateViewsManager.setInstance(mock); - var isVisible = true; - - await tester.pumpWidget( - MaterialApp( - home: Scaffold( - body: SafeArea( - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return CustomScrollView( - slivers: [ - SliverToBoxAdapter( - child: ElevatedButton( - onPressed: () { - setState(() { - isVisible = false; // make the widget invisible - }); - }, - child: const Text('Make invisible'), - ), - ), - SliverVisibility( - visible: isVisible, - maintainState: true, - sliver: InstabugSliverPrivateView( - sliver: const SliverToBoxAdapter( - child: SizedBox( - width: 40, - height: 40, - ), - ), - ), - ), - ], - ); - }, - ), - ), - ), - ), - ); - - await tester.tap(find.text('Make invisible')); - await tester.pump(const Duration(milliseconds: 300)); - - verify( - mock.unMask(any), - ).called( - 1, - ); - }); - }); -} diff --git a/scripts/init.sh b/scripts/init.sh index 7ccdb2abc..1191ca84f 100644 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -26,6 +26,10 @@ if [ -d "test" ]; then echo "Folder test and its contents removed" fi +if [ -d "example" ]; then + rm -rf "example" + echo "Folder example and its contents removed" +fi if command -v melos &> /dev/null then