Skip to content

Commit 38971ab

Browse files
init
1 parent 96e128a commit 38971ab

File tree

23 files changed

+167
-544
lines changed

23 files changed

+167
-544
lines changed

packages/instabug_flutter/android/src/main/java/com/instabug/flutter/InstabugFlutterPlugin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.instabug.flutter.modules.RepliesApi;
2020
import com.instabug.flutter.modules.SessionReplayApi;
2121
import com.instabug.flutter.modules.SurveysApi;
22+
import com.instabug.library.internal.crossplatform.InternalCore;
2223

2324
import java.util.concurrent.Callable;
2425

@@ -35,6 +36,7 @@ public class InstabugFlutterPlugin implements FlutterPlugin, ActivityAware {
3536
@SuppressLint("StaticFieldLeak")
3637
private static Activity activity;
3738

39+
3840
/**
3941
* Embedding v1
4042
*/

packages/instabug_flutter/android/src/main/java/com/instabug/flutter/modules/InstabugApi.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
import android.graphics.BitmapFactory;
77
import android.net.Uri;
88
import android.util.Log;
9+
910
import androidx.annotation.NonNull;
1011
import androidx.annotation.Nullable;
1112
import androidx.annotation.VisibleForTesting;
13+
1214
import com.instabug.flutter.generated.InstabugPigeon;
1315
import com.instabug.flutter.util.ArgsRegistry;
1416
import com.instabug.flutter.util.Reflection;
1517
import com.instabug.flutter.util.ThreadManager;
18+
import com.instabug.flutter.util.privateViews.ScreenshotCaptor;
1619
import com.instabug.library.Feature;
1720
import com.instabug.library.Instabug;
1821
import com.instabug.library.InstabugColorTheme;
@@ -21,13 +24,17 @@
2124
import com.instabug.library.Platform;
2225
import com.instabug.library.ReproConfigurations;
2326
import com.instabug.library.featuresflags.model.IBGFeatureFlag;
27+
import com.instabug.library.internal.crossplatform.InternalCore;
2428
import com.instabug.library.internal.module.InstabugLocale;
2529
import com.instabug.library.invocation.InstabugInvocationEvent;
2630
import com.instabug.library.model.NetworkLog;
31+
import com.instabug.library.screenshot.instacapture.ScreenshotRequest;
2732
import com.instabug.library.ui.onboarding.WelcomeMessage;
33+
2834
import io.flutter.FlutterInjector;
2935
import io.flutter.embedding.engine.loader.FlutterLoader;
3036
import io.flutter.plugin.common.BinaryMessenger;
37+
3138
import org.jetbrains.annotations.NotNull;
3239
import org.json.JSONObject;
3340

@@ -92,7 +99,9 @@ public Boolean isEnabled() {
9299

93100
@NotNull
94101
@Override
95-
public Boolean isBuilt() { return Instabug.isBuilt(); }
102+
public Boolean isBuilt() {
103+
return Instabug.isBuilt();
104+
}
96105

97106
@Override
98107
public void init(@NonNull String token, @NonNull List<String> invocationEvents, @NonNull String debugLogsLevel) {
@@ -441,4 +450,24 @@ public void networkLog(@NonNull Map<String, Object> data) {
441450
public void willRedirectToStore() {
442451
Instabug.willRedirectToStore();
443452
}
453+
454+
public static void setScreenshotCaptor(ScreenshotCaptor screenshotCaptor,InternalCore internalCore) {
455+
internalCore._setScreenshotCaptor(new com.instabug.library.screenshot.ScreenshotCaptor() {
456+
@Override
457+
public void capture(@NonNull ScreenshotRequest screenshotRequest) {
458+
screenshotCaptor.capture(new ScreenshotCaptor.CapturingCallback() {
459+
@Override
460+
public void onCapturingFailure(Throwable throwable) {
461+
screenshotRequest.getListener().onCapturingFailure(throwable);
462+
}
463+
464+
@Override
465+
public void onCapturingSuccess(Bitmap bitmap) {
466+
screenshotRequest.getListener().onCapturingSuccess(bitmap);
467+
}
468+
});
469+
}
470+
});
471+
}
472+
444473
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.instabug.flutter.util.privateViews;
2+
3+
import android.graphics.Bitmap;
4+
5+
public interface ScreenshotCaptor {
6+
public void capture(CapturingCallback listener);
7+
8+
public interface CapturingCallback {
9+
public void onCapturingFailure(Throwable throwable);
10+
11+
public void onCapturingSuccess(Bitmap bitmap);
12+
}
13+
}

packages/instabug_flutter/android/src/test/java/com/instabug/flutter/InstabugApiTest.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@
3636
import com.instabug.library.ReproConfigurations;
3737
import com.instabug.library.ReproMode;
3838
import com.instabug.library.featuresflags.model.IBGFeatureFlag;
39+
import com.instabug.library.internal.crossplatform.InternalCore;
3940
import com.instabug.library.invocation.InstabugInvocationEvent;
4041
import com.instabug.library.model.NetworkLog;
42+
import com.instabug.library.screenshot.ScreenshotCaptor;
4143
import com.instabug.library.ui.onboarding.WelcomeMessage;
4244

4345
import org.json.JSONObject;
@@ -59,6 +61,7 @@
5961
import java.util.concurrent.Callable;
6062

6163
import io.flutter.plugin.common.BinaryMessenger;
64+
6265
import org.mockito.verification.VerificationMode;
6366

6467
public class InstabugApiTest {
@@ -349,11 +352,11 @@ public void testClearAllExperiments() {
349352

350353
@Test
351354
public void testAddFeatureFlags() {
352-
Map<String,String > featureFlags = new HashMap<>();
353-
featureFlags.put("key1","variant1");
355+
Map<String, String> featureFlags = new HashMap<>();
356+
featureFlags.put("key1", "variant1");
354357
api.addFeatureFlags(featureFlags);
355-
List<IBGFeatureFlag> flags=new ArrayList<IBGFeatureFlag>();
356-
flags.add(new IBGFeatureFlag("key1","variant1"));
358+
List<IBGFeatureFlag> flags = new ArrayList<IBGFeatureFlag>();
359+
flags.add(new IBGFeatureFlag("key1", "variant1"));
357360
mInstabug.verify(() -> Instabug.addFeatureFlags(flags));
358361
}
359362

@@ -598,4 +601,12 @@ public void testWillRedirectToStore() {
598601
api.willRedirectToStore();
599602
mInstabug.verify(Instabug::willRedirectToStore);
600603
}
604+
605+
@Test
606+
public void testSetScreenshotCaptor() {
607+
InternalCore internalCore = spy(InternalCore.INSTANCE);
608+
609+
InstabugApi.setScreenshotCaptor(any(), internalCore);
610+
verify(internalCore)._setScreenshotCaptor(any(ScreenshotCaptor.class));
611+
}
601612
}

packages/instabug_flutter/example/ios/Podfile.lock

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,28 @@ PODS:
88

99
DEPENDENCIES:
1010
- Flutter (from `Flutter`)
11+
- Instabug (from `https://ios-releases.instabug.com/custom/feature-flutter-private-views-base/13.4.2/Instabug.podspec`)
1112
- instabug_flutter (from `.symlinks/plugins/instabug_flutter/ios`)
1213
- OCMock (= 3.6)
1314

1415
SPEC REPOS:
1516
trunk:
16-
- Instabug
1717
- OCMock
1818

1919
EXTERNAL SOURCES:
2020
Flutter:
2121
:path: Flutter
22+
Instabug:
23+
:podspec: https://ios-releases.instabug.com/custom/feature-flutter-private-views-base/13.4.2/Instabug.podspec
2224
instabug_flutter:
2325
:path: ".symlinks/plugins/instabug_flutter/ios"
2426

2527
SPEC CHECKSUMS:
2628
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
27-
Instabug: 7a71890217b97b1e32dbca96661845396b66da2f
29+
Instabug: 7aacd5099c11ce96bc49dda40eba0963c06acccc
2830
instabug_flutter: a2df87e3d4d9e410785e0b1ffef4bc64d1f4b787
2931
OCMock: 5ea90566be239f179ba766fd9fbae5885040b992
3032

31-
PODFILE CHECKSUM: 8f7552fd115ace1988c3db54a69e4a123c448f84
33+
PODFILE CHECKSUM: 02e3295e1482e04d2cbd38390c8ea91a5c0c2ff1
3234

3335
COCOAPODS: 1.14.3
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
## 0.0.1
1+
# Changelog
22

3-
* TODO: Describe initial release.
3+
## [UnReleased](https://github.com/Instabug/)
4+
5+
### Added
6+
7+
- Add support for masking private views during screen capturing ([#527](https://github.com/Instabug/Instabug-Flutter/pull/527)).

packages/instabug_private_views/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void main() {
3535
invocationEvents: [InvocationEvent.floatingButton],
3636
);
3737
38-
ReproSteps.enablePrivateViews();
38+
ReproSteps.enableMaskingPrivateViews();
3939
4040
runApp(MyApp());
4141

packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/InstabugPrivateViewsPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public void onDetachedFromActivity() {
8282

8383
private void register(BinaryMessenger messenger, FlutterRenderer renderer) {
8484
privateViewManager = new PrivateViewManager(new InstabugPrivateViewPigeon.InstabugPrivateViewFlutterApi(messenger), new PixelCopyCaptureManager(), new BoundryCaptureManager(renderer));
85-
InstabugPrivateView instabugPrivateView=new InstabugPrivateView(messenger,privateViewManager, InternalCore.INSTANCE);
85+
InstabugPrivateView.init(messenger,privateViewManager);
8686

8787
}
8888
}

packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/InstabugPrivateView.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,38 @@
22

33
import androidx.annotation.NonNull;
44

5+
import com.instabug.flutter.generated.InstabugLogPigeon;
6+
import com.instabug.flutter.modules.InstabugApi;
7+
import com.instabug.flutter.modules.InstabugLogApi;
8+
import com.instabug.flutter.util.privateViews.ScreenshotCaptor;
59
import com.instabug.instabug_private_views.generated.InstabugPrivateViewPigeon;
610
import com.instabug.library.internal.crossplatform.InternalCore;
7-
import com.instabug.library.screenshot.ScreenshotCaptor;
811
import com.instabug.library.screenshot.instacapture.ScreenshotRequest;
912

1013
import io.flutter.plugin.common.BinaryMessenger;
1114

1215
public class InstabugPrivateView implements InstabugPrivateViewPigeon.InstabugPrivateViewHostApi {
1316
PrivateViewManager privateViewManager;
14-
private final InternalCore internalCore;
1517

16-
public InstabugPrivateView(BinaryMessenger messenger, PrivateViewManager privateViewManager, InternalCore internalCore) {
18+
public static void init(BinaryMessenger messenger, PrivateViewManager privateViewManager) {
19+
final InstabugPrivateView api = new InstabugPrivateView(messenger,privateViewManager);
20+
InstabugPrivateViewPigeon.InstabugPrivateViewHostApi.setup(messenger, api);
21+
}
22+
23+
public InstabugPrivateView(BinaryMessenger messenger, PrivateViewManager privateViewManager) {
1724
this.privateViewManager = privateViewManager;
18-
this.internalCore = internalCore;
1925
InstabugPrivateViewPigeon.InstabugPrivateViewHostApi.setup(messenger, this);
2026

2127
}
2228

2329
@Override
2430
public void init() {
25-
internalCore._setScreenshotCaptor(new ScreenshotCaptor() {
31+
InstabugApi.setScreenshotCaptor(new ScreenshotCaptor() {
2632
@Override
27-
public void capture(@NonNull ScreenshotRequest screenshotRequest) {
28-
privateViewManager.mask(screenshotRequest.getListener());
33+
public void capture(CapturingCallback listener) {
34+
privateViewManager.mask(listener);
35+
2936
}
30-
});
37+
},InternalCore.INSTANCE);
3138
}
3239
}

packages/instabug_private_views/android/src/main/java/com/instabug/instabug_private_views/modules/PrivateViewManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@
1010
import androidx.annotation.VisibleForTesting;
1111

1212
import com.instabug.flutter.util.ThreadManager;
13+
import com.instabug.flutter.util.privateViews.ScreenshotCaptor;
1314
import com.instabug.instabug_private_views.generated.InstabugPrivateViewPigeon;
1415
import com.instabug.instabug_private_views.model.ScreenshotResult;
1516
import com.instabug.instabug_private_views.modules.capturing.CaptureManager;
1617
import com.instabug.instabug_private_views.modules.capturing.ScreenshotResultCallback;
17-
import com.instabug.library.screenshot.ScreenshotCaptor;
1818

1919
import java.util.List;
2020
import java.util.concurrent.CountDownLatch;
2121
import java.util.concurrent.ExecutorService;
2222
import java.util.concurrent.Executors;
2323
import java.util.concurrent.atomic.AtomicReference;
2424

25-
public class PrivateViewManager {
25+
public class PrivateViewManager {
2626
private static final String THREAD_NAME = "IBG-Flutter-Screenshot";
2727
public static final String EXCEPTION_MESSAGE = "IBG-Flutter-Screenshot: error capturing screenshot";
2828

packages/instabug_private_views/example/android/gradlew

100644100755
File mode changed.

packages/instabug_private_views/example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
1616
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
1717
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
18+
BE133A632CD831A500FEADB5 /* PrivateViewHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BE133A622CD831A500FEADB5 /* PrivateViewHostApiTests.m */; };
1819
BE9F8D392CD5C068003ADA97 /* PrivateViewApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D382CD5C068003ADA97 /* PrivateViewApiTests.m */; };
1920
/* End PBXBuildFile section */
2021

@@ -64,6 +65,7 @@
6465
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6566
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 = "<group>"; };
6667
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 = "<group>"; };
68+
BE133A622CD831A500FEADB5 /* PrivateViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrivateViewHostApiTests.m; sourceTree = "<group>"; };
6769
BE9F8D382CD5C068003ADA97 /* PrivateViewApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PrivateViewApiTests.m; sourceTree = "<group>"; };
6870
BE9F8D3A2CD5C06A003ADA97 /* RunnerTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RunnerTests-Bridging-Header.h"; sourceTree = "<group>"; };
6971
/* End PBXFileReference section */
@@ -93,6 +95,7 @@
9395
children = (
9496
BE9F8D382CD5C068003ADA97 /* PrivateViewApiTests.m */,
9597
BE9F8D3A2CD5C06A003ADA97 /* RunnerTests-Bridging-Header.h */,
98+
BE133A622CD831A500FEADB5 /* PrivateViewHostApiTests.m */,
9699
);
97100
path = RunnerTests;
98101
sourceTree = "<group>";
@@ -390,6 +393,7 @@
390393
buildActionMask = 2147483647;
391394
files = (
392395
BE9F8D392CD5C068003ADA97 /* PrivateViewApiTests.m in Sources */,
396+
BE133A632CD831A500FEADB5 /* PrivateViewHostApiTests.m in Sources */,
393397
);
394398
runOnlyForDeploymentPostprocessing = 0;
395399
};
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#import <Foundation/Foundation.h>
2+
#import <XCTest/XCTest.h>
3+
#import <OCMock/OCMock.h>
4+
#import "PrivateViewApi.h"
5+
#import "instabug_flutter/InstabugApi.h"
6+
#import "PrivateViewHostApi.h"
7+
8+
@interface PrivateViewHostApiTests : XCTestCase
9+
10+
@property (nonatomic, strong) PrivateViewHostApi *api;
11+
@property (nonatomic, strong) id privateViewApiMock;
12+
13+
@end
14+
15+
@implementation PrivateViewHostApiTests
16+
17+
- (void)setUp {
18+
[super setUp];
19+
20+
// Set up a mock for PrivateViewApi
21+
self.privateViewApiMock = OCMClassMock([PrivateViewApi class]);
22+
23+
// Initialize the PrivateViewHostApi instance
24+
self.api = [[PrivateViewHostApi alloc] init];
25+
self.api.privateViewApi = self.privateViewApiMock;
26+
}
27+
28+
- (void)tearDown {
29+
self.api = nil;
30+
self.privateViewApiMock = nil;
31+
[super tearDown];
32+
}
33+
34+
- (void)testInitWithError_setsScreenshotMaskingHandler {
35+
// Define an expectation for the screenshot masking handler
36+
UIImage *mockScreenshot = [[UIImage alloc] init];
37+
UIImage *mockMaskedImage = [[UIImage alloc] init];
38+
FlutterError *error = nil;
39+
40+
41+
42+
OCMStub([self.privateViewApiMock mask:mockScreenshot completion:([OCMArg invokeBlockWithArgs:mockMaskedImage, nil])]);
43+
44+
45+
// Call initWithError and set up the screenshot masking handler
46+
[self.api initWithError:&error];
47+
48+
// Invoke the screenshot masking handler
49+
void (^completionHandler)(UIImage * _Nullable) = ^(UIImage * _Nullable maskedImage) {
50+
XCTAssertEqual(maskedImage, mockMaskedImage, @"The masked image should be returned by the completion handler.");
51+
};
52+
[InstabugApi setScreenshotMaskingHandler:^(UIImage * _Nonnull screenshot, void (^ _Nonnull completion)(UIImage * _Nullable)) {
53+
completionHandler(screenshot);
54+
}];
55+
}
56+
57+
@end

0 commit comments

Comments
 (0)