-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: replace photo library detection with human face detection #267
Conversation
}() | ||
|
||
private static var ph_human_face_detected_key: UInt8 = 0 | ||
var ph_human_face_detected: Bool? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where we mem-cache the face detection so we avoid detecting multiple times per resource
// with maskAllImages options (e.g in this case this was a blurred background view of a UIPickerView) | ||
// Let’s be prudent and add a general check on internal classes starting with _UI. | ||
// We may need to be more explicit in the future | ||
String(describing: view).starts(with: "<_UI") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we should be explicit here for "<_UICutoutShadowView>" but a general test for internal types here seemed like a good idea at the time
// No way of checking if there's actual content in the image or not | ||
config.sessionReplayConfig.maskAllImages || view.isNoCapture() | ||
// sensitive, regardless | ||
if view.isNoCapture() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't refactor view.isNoCapture()
yet to keep the scope low
} | ||
|
||
// an animated image view (e.g spinner view) is most likely not a sensitive asset | ||
if isAnimatedImageView(view) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Came across system loaders in SwiftUI. But could also be gif support through UIImage.animatedImageNamed()
constructor
/// Default: true | ||
@objc public var maskPhotoLibraryImages: Bool = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot do this otherwise we will break people's builds on react native and iOS.
If needed we would need a major bump in the sdk version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can leave and mark as deprecated for next major release? (and also turn default to false - won't have an impact but just to be clear)
Just an idea: Maybe this can be a separated PR so we can land this asap as this one might drag a bit longer? |
IIRC, we added those configs because of the photo user picker, which is solved with the The problem is that the IMO we should just deprecate the WDYT? |
Yeah, that's correct
Agreed. The initial thought was to come up with an alternative to the originally intended functionality - thinking about this again I fully agree. It's indeed an niche use case - any images other than the picker that are in-app are controlled fully by the developers so they can manually mask themselves and run any other logic, like face detection, they want. Let’s scrap this.
Agreed |
see: #268 |
💡 Motivation and Context
Looks like we were very optimistic in our ability to detect if a
UIImage
originated from user's photo library. The initial thought was to detect_assetName
for a UIImage that was not an image asset or a symbol image. Turns out that some system generated images, as well as remotely loaded images may also contain aUUID
value in "_assetName". So it turns out that this plan will not work.I tried experimenting with extracting GPS, TIFF and EXIF metadata from the image in an attempt to detect an image that was captured with geolocation, camera make/model or a dateTimeDigitized meta - rationale was that this would hint for a photo library image. Turns out that this metadata is removed by the OS when selecting a photo from photo library, and otherwise not accessible unless through photo library permissions. So this plan will not work as well.
In the end, I decided to repurpose the old
maskPhotoLibraryImages
config withmaskImagesWithHumanFaces
as an attempt to at least protect user's photo PII. UsedCIDetector
which is designed for real-time detection during video capture. In our case, the detection is only executed once and cached for eachCGImage
. Considering that we run at 1fps this doesn't seem to have a great impact performance (also opted forCIDetectorAccuracyLow
which is even faster here). Added support for SwiftUI as well here.As a fly-by, I noticed that
maskAllImage
we were also masking UIPickerView's background as well (system adds a blurred background in menu popup which we visit when iterating over the view hierarchy). Added aisSystemImageView
check for thatmaskAllImage
we were also masking some animated images (e.g loader) in SwiftUI. Added aisAnimatedImageView
check for thatOriginal slack thread: https://posthog.slack.com/archives/C03PB072FMJ/p1732875958511529
TODO:
💚 How did you test it?
📝 Checklist