Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- Track low power mode in device context (#7777)

## 9.10.0

### Features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
public var isiOSAppOnMac: Bool?
public var isMacCatalystApp: Bool?
public var isiOSAppOnVisionOS: Bool?
public var isLowPowerModeEnabled: Bool?
}

public var overrides = Override()
Expand Down Expand Up @@ -50,4 +51,9 @@
public var isiOSAppOnVisionOS: Bool {
return overrides.isiOSAppOnVisionOS ?? ProcessInfo.processInfo.isiOSAppOnVisionOS
}

@available(macOS 12.0, *)
public var isLowPowerModeEnabled: Bool {
return overrides.isLowPowerModeEnabled ?? ProcessInfo.processInfo.isLowPowerModeEnabled
}
}
4 changes: 4 additions & 0 deletions Sources/Swift/Helper/SentryExtraContextProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
default:
SentrySDKLog.warning("Unexpected thermal state enum value: \(thermalState)")
}

if #available(macOS 12.0, *) {
extraDeviceContext["low_power_mode"] = NSNumber(value: processInfoWrapper.isLowPowerModeEnabled)
Comment thread
itaybre marked this conversation as resolved.
}

#if (os(iOS)) && !SENTRY_NO_UI_FRAMEWORK
if deviceWrapper.orientation != .unknown {
Expand Down
5 changes: 4 additions & 1 deletion Sources/Swift/Helper/SentryProcessInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@

@available(macOS 12.0, *)
var isMacCatalystApp: Bool { get }

var isiOSAppOnVisionOS: Bool { get }

@available(macOS 12.0, *)
var isLowPowerModeEnabled: Bool { get }
}

// This is needed because a file that only contains an @objc extension will get automatically stripped out
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ final class SentryCrashIntegration<Dependencies: CrashIntegrationProvider>: NSOb
name: NSLocale.currentLocaleDidChangeNotification,
object: nil
)

if #available(macOS 12.0, *) {
NotificationCenter.default.removeObserver(
self,
name: NSNotification.Name.NSProcessInfoPowerStateDidChange,
object: nil
)
}
}

// MARK: - Crash Handler
Expand Down Expand Up @@ -241,6 +249,16 @@ final class SentryCrashIntegration<Dependencies: CrashIntegrationProvider>: NSOb
name: NSLocale.currentLocaleDidChangeNotification,
object: nil
)

if #available(macOS 12.0, *) {
updateLowPowerModeContext()
NotificationCenter.default.addObserver(
self,
selector: #selector(powerStateDidChange),
name: NSNotification.Name.NSProcessInfoPowerStateDidChange,
object: nil
)
}
}

// Exposed to objc for the NotificationCenter in configureScope()
Expand All @@ -261,6 +279,29 @@ final class SentryCrashIntegration<Dependencies: CrashIntegrationProvider>: NSOb
}
}

@available(macOS 12.0, *)
@objc private func powerStateDidChange() {
updateLowPowerModeContext()
Comment thread
itaybre marked this conversation as resolved.
Outdated
}

@available(macOS 12.0, *)
private func updateLowPowerModeContext() {
let isLowPowerMode = ProcessInfo.processInfo.isLowPowerModeEnabled
SentrySDKInternal.currentHub().configureScope { scope in
var device: [String: Any]
let contextDictionary = scope.contextDictionary
if let existingDevice = contextDictionary[SENTRY_CONTEXT_DEVICE_KEY] as? [String: Any] {
device = existingDevice
} else {
device = [:]
}

device["low_power_mode"] = isLowPowerMode

scope.setContext(value: device, key: SENTRY_CONTEXT_DEVICE_KEY)
}
}

// MARK: - Tracing Configuration

private func configureTracingWhenCrashing() {
Expand Down
20 changes: 20 additions & 0 deletions Tests/SentryTests/Helper/SentryExtraContextProviderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,24 @@ final class SentryExtraContextProviderTests: XCTestCase {
XCTAssertEqual(try XCTUnwrap(device["thermal_state"] as? String), "critical")
}

func testLowPowerMode() throws {
let sut = fixture.getSut()
fixture.processWrapper.overrides.isLowPowerModeEnabled = true

let actualContext = sut.getExtraContext()
let device = try XCTUnwrap(actualContext["device"] as? [String: Any])

XCTAssertTrue(try XCTUnwrap(device["low_power_mode"] as? Bool))
}

func testLowPowerModeDisabled() throws {
let sut = fixture.getSut()
fixture.processWrapper.overrides.isLowPowerModeEnabled = false

let actualContext = sut.getExtraContext()
let device = try XCTUnwrap(actualContext["device"] as? [String: Any])

XCTAssertFalse(try XCTUnwrap(device["low_power_mode"] as? Bool))
}

}
Loading