Skip to content
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: Include app permissions with event #1984

Merged
merged 29 commits into from
Aug 2, 2022

Conversation

kevinrenskers
Copy link
Contributor

@kevinrenskers kevinrenskers commented Jul 18, 2022

📜 Description

We're now including the status of some permissions, namely for Push Notifications, Location access, Media Library and Photo Library. This is added to the app context in every event. These permissions are cached.

We can easily add more permissions, but I figured we can do that in a separate PR, let's get this merged first if we like this approach. Also it would be a lot easier to add more permission once we drop iOS 9 😅

💡 Motivation and Context

Closes #1014

💚 How did you test it?

With the sample app and unit tests.

📝 Checklist

  • I reviewed the submitted code
  • I added tests to verify the changes
  • I updated the docs if needed
  • Review from the native team if needed
  • No breaking changes

🔮 Next steps

@github-actions
Copy link

github-actions bot commented Jul 18, 2022

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 708286a

@kevinrenskers
Copy link
Contributor Author

kevinrenskers commented Jul 18, 2022

This is still very much a Work In Progress, tests won't compile etc etc. But it would good to get an initial first look at this. The way I implemented this is with a SentryPermissionsObserver class which acts as the "cache", and it updates its values when the system permissions change.

There is one problem with this though: most of the system permissions do not have a way to observe permission changes. CLLocationManager is kind of unique in that you can assign a delegate and from then on locationManagerDidChangeAuthorization will be called. But for example for Push Notification permissions, there is nothing like that, we can only fetch the status on demand, which is an async method at that. So right now I solved it by listening to UIApplicationDidBecomeActiveNotification to update the value. but that's not a full solution, because if the app asks for push permissions and the user simply gives it in the native alert, UIApplicationDidBecomeActiveNotification is not called.

And it's the same with most of the other system permissions: you can read them on demand, but there is no way to be notified of changes. So what do we do? Reading them for every event will take too long (20 ms), so that's not an option. But sending the wrong values is arguably even worse.

@kevinrenskers
Copy link
Contributor Author

Alrighty, the UIApplicationDidBecomeActiveNotification notification is actually called when you grant permissions in the normal happy path flow. I simply was adding the permissions to the context only once at SDK start-up, instead of always for every event, so the values weren't updating. Now it all works.

@brustolin
Copy link
Contributor

brustolin commented Jul 19, 2022

Alrighty, the UIApplicationDidBecomeActiveNotification notification is actually called when you grant permissions in the normal happy path flow

That's interesting. If every time a permission popup disappear we receive a UIApplicationDidBecomeActiveNotification this might be the solution for almost every permission.

If that is not the case, we could use swizzling to hook into the "notifications".

@kevinrenskers
Copy link
Contributor Author

276 test failures in macOS? And I can't run them locally because the test always crashes with The file “io.sentry” couldn’t be saved in the folder “Caches”.

@kevinrenskers
Copy link
Contributor Author

I am getting some UI test failures, but all the other stuff (finally!) succeeds. I am surprised by the UI test failures though, as I haven't changed those tests, and only added a button to the home screen which isn't tested in any way.

@kevinrenskers kevinrenskers marked this pull request as ready for review July 20, 2022 11:37
@balavor
Copy link
Contributor

balavor commented Jul 21, 2022

I don't have existing examples, but we've experienced floating crashes inside app extensions, where some features are not expected to be used. Those have been fixed by now, but there might be new cases, so I wish we could have complete control of those requests using our feature toggles on the device.

@kevinrenskers
Copy link
Contributor Author

@philipphofmann @brustolin do you think we should add an option for this? And should it default to on or off?

@philipphofmann
Copy link
Member

Hey there,

Could you please share if there'd be a toggle to turn off that feature? It is something that may return invalid results or even crash. Both cases are primarily applicable to iOS app extensions.

We don't have a toggle for that feature on Android getsentry/sentry-java#2018, and I think we shouldn't add one if we can safely write the code so it doesn't crash on app extensions. Would that be possible, @kevinrenskers?

@kevinrenskers
Copy link
Contributor Author

Would these permission checks crash in extensions? Is that documented somewhere? I need to look into this. We're just reading permissions, I can hardly believe this would cause a crash 🤔

I guess I'll create an extension and read these permissions, see what happens. As I've never built an extension before, that'll be a fun exercise by itself :)

@balavor
Copy link
Contributor

balavor commented Jul 22, 2022

Yeah, we have an app extension as our primary product on iOS instead of the app itself, so I just want to highlight that 🙃

@kevinrenskers
Copy link
Contributor Author

I've created an IntentUI extension and a Widget extension, and in neither of them did accessing any of these permissions properties cause any problems. Personally I don't think this would ever crash, but just to be sure I added a check to only read permissions when we're running the main app.

@brustolin
Copy link
Contributor

I added a check to only read permissions when we're running the main app

I like this solution, but please create an issue for us to investigate this further in the future, I think this feature could be useful for extensions, especially widgets.

Copy link
Member

@armcknight armcknight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good. I wonder if we couldn't also gather info on the existence of required Plist keys for various permissions requests. The absence of a required perm key in the plist can lead to crashes, so that'd be a quick win diagnostic.

I'm not sure if we can also check for required entitlements in the bundle at runtime, but that's another avenue worth exploring.

See

@kevinrenskers
Copy link
Contributor Author

Asking for permission without the correct things in the info.plist will cause a crash, but merely checking if we have permission doesn't cause a crash (in my testing).

@armcknight
Copy link
Member

Oh, I wasn't worrying about us causing a crash, more thinking that we could use this as a diagnostic if the app caused such a crash. Do we [plan to] swizzle any CLLocation API?

* master:
  ci: benchmarking and profile generation improvements (#2022)
  release: 7.23.0
  fix: Bad merge on CHANGELOG.md (#2020)
  fix: Log empty samples instead of collecting stacks for idle threads (#2013)
  fix: Handle failure to read thread priority gracefully (#2015)
  fix: Remove logging that could occur while a thread is suspended (#2014)
  fix: Use constant for max thread name size instead of magic number (#2012)
  Disable flaky tesDefaultMaxEnvelopesConcurrent (#2018)
  Fix build failure in unit tests (#2019)
  Fix address sanitizer compilation error (#1996)
  fix: Sauce labs iPhone 13 pro iOS version
  feat: Add transaction to baggage and trace headers (#1992)
  ci: fix ui thread starvation in benchmarks (#2009)
  fix: Add more descriptive deprecation message for enableProfiling (#2011)
  feat: Add sampling configuration for profiling (#2004)
  fix log message option name (#2006)
  meta: add armcknight as a codeowner (#2008)
  release: 7.22.0
  fix: Disable broken LaunchUITests to unblock release (#2003)

# Conflicts:
#	Samples/iOS-Swift/iOS-Swift/ViewControllers/PerformanceViewController.swift
@kevinrenskers
Copy link
Contributor Author

That might be a nice future feature to add, can you make an issue to keep track of that? I don't think it should necessarily go into this PR. I was really hoping to merge this soon so we can build on top of it.

@kevinrenskers
Copy link
Contributor Author

I added a check to only read permissions when we're running the main app

I like this solution, but please create an issue for us to investigate this further in the future, I think this feature could be useful for extensions, especially widgets.

#2026

@kevinrenskers
Copy link
Contributor Author

One failure in a benchmarking test. How can I run this locally? And what is the implication? That this new feature is adding overhead?

@brustolin
Copy link
Contributor

brustolin commented Aug 1, 2022

You can run the test under iOS-Swift sample project, "PerformanceBenchmarks > SentrySDKPerformanceBenchmarkTests.m".
This was added by the profiling team, Im not really sure what it does.
Can you figure it out whether this is flack and we should ping then, or is something that was added to the PR? Thanks!!

@kevinrenskers
Copy link
Contributor Author

Damn, this is the most annoying test to run, ever. It takes forever. The error it runs into on CI is that usagePercentage is equal to zero, and it expects it to be higher than zero. This is definitely unrelated to this PR.

@kevinrenskers
Copy link
Contributor Author

Pushed another commit without changes and yea now they succeed just fine. I think the profiling team needs to look at their tests.

Copy link
Contributor

@brustolin brustolin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kevinrenskers kevinrenskers merged commit 398f6b2 into master Aug 2, 2022
@kevinrenskers kevinrenskers deleted the feat/1014-include-app-permissions branch August 2, 2022 13:37
kevinrenskers added a commit that referenced this pull request Aug 2, 2022
* master:
  feat: Include app permissions with event (#1984)

# Conflicts:
#	Sources/Sentry/SentryClient.m
#	Tests/SentryTests/SentryClientTests.swift
kevinrenskers added a commit that referenced this pull request Aug 2, 2022
* master:
  feat: Include app permissions with event (#1984)
kevinrenskers added a commit that referenced this pull request Aug 2, 2022
* master:
  feat: Include app permissions with event (#1984)

# Conflicts:
#	Sentry.xcodeproj/project.pbxproj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Include app permissions in events
5 participants